Python: neden * * * daha hızlı ve daha Karekök()?
Benim kodu optimize ederken aşağıdaki anladım:
>>> from timeit import Timer as T
>>> T(lambda : 1234567890 / 4.0).repeat()
[0.22256922721862793, 0.20560789108276367, 0.20530295372009277]
>>> from __future__ import division
>>> T(lambda : 1234567890 / 4).repeat()
[0.14969301223754883, 0.14155197143554688, 0.14141488075256348]
>>> T(lambda : 1234567890 * 0.25).repeat()
[0.13619112968444824, 0.1281130313873291, 0.12830305099487305]
ve ayrıca:
>>> from math import sqrt
>>> T(lambda : sqrt(1234567890)).repeat()
[0.2597470283508301, 0.2498021125793457, 0.24994492530822754]
>>> T(lambda : 1234567890 ** 0.5).repeat()
[0.15409398078918457, 0.14059877395629883, 0.14049601554870605]
Python C uygulanan biçimi ile bir ilgisi yoktur sanırım, ama kimseye niye böyle olduğunu açıklamak ister mi acaba?
CEVAP
Sonuçlar için (biraz) beklenmedik bir nedenle Python sabit ifade kayan nokta çarpma ve üs ilgili kat gibi görünüyor, ama bölünme değil. math.sqrt()
tamamen bunun için bayt kodu var ve bir işlev çağrısı içerir çünkü farklı bir canavar.
Üzerinde Python 2.6.5, aşağıdaki kodu:
x1 = 1234567890.0 / 4.0
x2 = 1234567890.0 * 0.25
x3 = 1234567890.0 ** 0.5
x4 = math.sqrt(1234567890.0)
aşağıdaki bytecodes derler:
# x1 = 1234567890.0 / 4.0
4 0 LOAD_CONST 1 (1234567890.0)
3 LOAD_CONST 2 (4.0)
6 BINARY_DIVIDE
7 STORE_FAST 0 (x1)
# x2 = 1234567890.0 * 0.25
5 10 LOAD_CONST 5 (308641972.5)
13 STORE_FAST 1 (x2)
# x3 = 1234567890.0 ** 0.5
6 16 LOAD_CONST 6 (35136.418286444619)
19 STORE_FAST 2 (x3)
# x4 = math.sqrt(1234567890.0)
7 22 LOAD_GLOBAL 0 (math)
25 LOAD_ATTR 1 (sqrt)
28 LOAD_CONST 1 (1234567890.0)
31 CALL_FUNCTION 1
34 STORE_FAST 3 (x4)
Gördüğünüz gibi, çarpma ve üs kodu derlenmiş yapmış oldukları için hiçbir zaman alır. Bölünme zamanı olur bu yana uzun sürer. Kare Kök dört en hesaplama açısından pahalı bir işlem değil sadece, aynı zamanda Diğerleri değil çeşitli giderleri (öznitelik Arama, arama işlevi, vb) ödenmez.
Eğer sabit katlama etkisini ortadan kaldırmak, küçük çarpma ve bölme ayırmak için var:
In [16]: x = 1234567890.0
In [17]: %timeit x / 4.0
10000000 loops, best of 3: 87.8 ns per loop
In [18]: %timeit x * 0.25
10000000 loops, best of 3: 91.6 ns per loop
math.sqrt(x)
aslında biraz daha hızlı muhtemelen ikincisi özel bir durum çünkü x ** 0.5
, ve bu nedenle daha verimli bir şekilde yapılabilir, genel giderler " diye sordum
In [19]: %timeit x ** 0.5
1000000 loops, best of 3: 211 ns per loop
In [20]: %timeit math.sqrt(x)
10000000 loops, best of 3: 181 ns per loop
2011-11-16 düzenleme:Sürekli ifade katlanır Piton yılanı deliğinden doktoru tarafından yapılır. Kaynak kodu (peephole.c
) neden sürekli bölüm katlanmış değil açıklayan aşağıdaki yorum içerir:
case BINARY_DIVIDE:
/* Cannot fold this operation statically since
the result can depend on the run-time presence
of the -Qnew flag */
return 0;
-Qnew
bayrak "doğru bölüm" PEP 238 tanımlanmış sağlar.
Neden Python kodunu daha hızlı bir işl...
Python ile daha hızlı olan: x**.5 veya...
Neden python pandalar birleştirir daha...
Neden aralığında loop() Python bir sür...
Neden sıralanmamış bir dizi daha hızlı...