(Macbook Pro 2.8GHz i7 tüm zamanlamaları) bilmektir: Eğer küresel her zaman yukarı bakmak gerekir çünkü
>>> import sys, timeit
>>> sys.version_info
sys.version_info(major=2, minor=7, micro=12, releaselevel='final', serial=0)
>>> timeit.timeit('divmod(n, d)', 'n, d = 42, 7')
0.1473848819732666
>>> timeit.timeit('n // d, n % d', 'n, d = 42, 7')
0.10324406623840332
divmod()
buradaki görevi bir dezavantaj olduğunu. (A timeit
zaman deneme tüm değişkenler yereldir) yerel bir onu Bağlama biraz performansı artırır:
>>> timeit.timeit('dm(n, d)', 'n, d = 42, 7; dm = divmod')
0.13460898399353027
ama divmod()
bir işlev çağrısı sırasında geçerli çerçeveyi korumak gerekmez çünkü operatörler hala kazanabilir yürütülür: //
ve %
varyantı daha opcodes kullanır, ancak CALL_FUNCTION
baytkodu akıllıca bir ayı, performans
>>> import dis
>>> dis.dis(compile('divmod(n, d)', '', 'exec'))
1 0 LOAD_NAME 0 (divmod)
3 LOAD_NAME 1 (n)
6 LOAD_NAME 2 (d)
9 CALL_FUNCTION 2
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE
>>> dis.dis(compile('(n // d, n % d)', '', 'exec'))
1 0 LOAD_NAME 0 (n)
3 LOAD_NAME 1 (d)
6 BINARY_FLOOR_DIVIDE
7 LOAD_NAME 0 (n)
10 LOAD_NAME 1 (d)
13 BINARY_MODULO
14 BUILD_TUPLE 2
17 POP_TOP
18 LOAD_CONST 0 (None)
21 RETURN_VALUE
.
PyPy'de, küçük tamsayılar için çok fazla bir fark yoktur;
>>>> import platform, sys, timeit
>>>> platform.python_implementation(), sys.version_info
('PyPy', (major=2, minor=7, micro=10, releaselevel='final', serial=42))
>>>> timeit.timeit('divmod(n, d)', 'n, d = 42, 7', number=10**9)
0.5659301280975342
>>>> timeit.timeit('n // d, n % d', 'n, d = 42, 7', number=10**9)
0.5471200942993164
(ben fark gerçekten, PyPy blazingly ne kadar küçük göstermek için 1 milyar kadar tekrar sayısını krank zorunda: opcodes sahip küçük hız avantajı C tamsayı aritmetik hızlı bir şekilde yön altında eriyip gider Burada hızlı). sayılar olsun Ancak
,
büyük, ülke mile tarafından
divmod()
galibiyet: >>>> timeit.timeit('divmod(n, d)', 'n, d = 2**74207281 - 1, 26', number=100)
17.620037078857422
>>>> timeit.timeit('n // d, n % d', 'n, d = 2**74207281 - 1, 26', number=100)
34.44323515892029
(şimdi aşağı ayarlamak zorunda kıyasla 10 kat tekrarlama sayısı hobbs 'sayıları, sadece makul bir sürede sonuç elde etmek için).
Bunun nedeni, PyPy'nin artık tamsayıları C tamsayıları olarak kaldıramayacağıdır; Eğer sys.maxint
ve sys.maxint + 1
kullanmak arasındaki zamanlamaları çarpıcı farkı görebilirsiniz: Eğer aritmetik işlemler çok hızlı işlev çağrılarına karşılaştırılır "küçük" yerli tamsayılar, kullanıyorsanız
>>>> timeit.timeit('divmod(n, d)', 'import sys; n, d = sys.maxint, 26', number=10**7)
0.008622884750366211
>>>> timeit.timeit('n // d, n % d', 'import sys; n, d = sys.maxint, 26', number=10**7)
0.007693052291870117
>>>> timeit.timeit('divmod(n, d)', 'import sys; n, d = sys.maxint + 1, 26', number=10**7)
0.8396248817443848
>>>> timeit.timeit('n // d, n % d', 'import sys; n, d = sys.maxint + 1, 26', number=10**7)
1.0117690563201904
Neden öğrenmek için 'timeit' kullanmıyoruz? –
İşlev çağrısı ek yükü ('CALL_FUNCTION 'bytecode) muhtemelen ilk sürümde daha yavaş yürütmeye neden olur, ancak' timeit 'emin olmak için bir yoldur. –
Hangi uygulama? –