divmod()是否比使用%和运算符快?

divmod()是否比使用%和运算符快?,第1张

divmod()是否比使用%和//运算符快?

要测量就知道(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


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5640245.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存