要测量就知道(Macbook Pro 2.8Ghz i7上的所有计时):
>>> import sys, timeit>>> sys.version_infosys.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()函数在这里处于劣势,因为您每次都需要查找全局变量。将其绑定到本地(
timeit时间试用中的所有变量都是本地)可以稍微提高性能:
>>> timeit.timeit('dm(n, d)', 'n, d = 42, 7; dm = divmod')0.13460898399353027
但是运算符仍然会获胜,因为
divmod()执行函数调用时不必保留当前帧:
>>> import dis>>> dis.dis(compile('divmod(n, d)', '', 'exec')) 10 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')) 10 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
在
//和
%变种使用更多的 *** 作码,但
CALL_FUNCTION字节码是熊,性能明智的。
在PyPy中,对于小的整数并没有太大的区别。在C整数运算的绝对速度下, *** 作码所具有的较小的速度优势就消失了:
>>>> 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
(我不得不将重复次数提高到10亿次,以表明差异的确有多小,这里PyPy的速度非常快)。
但是,当数字变 大时 ,将
divmod()赢得一个国家英里 :
>>>> 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
(与霍布斯的数字相比,我现在不得不将重复次数 调低 10倍,以在合理的时间内获得结果)。
这是因为PyPy不再可以将这些整数拆箱为C整数;您可以看到使用
sys.maxint和之间的时间差异显着
sys.maxint + 1:
>>>> 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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)