我正在尝试优化我正在修改的程序,当我注意到 dovalue = i % 65536
似乎比 do 运行得更慢时value = i % (2**16)
。
为了测试这一点,我运行了以下程序:
import cProfile
import pstats
AMOUNT = 100000000
def test1():
for i in xrange(AMOUNT):
value = i % 65536
return
def test2():
for i in xrange(AMOUNT):
value = i % (256**2)
return
def test3():
for i in xrange(AMOUNT):
value = i % (16**4)
return
def test4():
for i in xrange(AMOUNT):
value = i % (4**8)
return
def test5():
for i in xrange(AMOUNT):
value = i % (2**16)
return
def run_tests():
test1()
test2()
test3()
test4()
test5()
return
if __name__ == '__main__':
cProfile.run('run_tests()', 'results')
stats = pstats.Stats('results')
stats.sort_stats('calls', 'nfl')
stats.print_stats()
...产生以下输出:
Fri May 11 15:11:59 2012 results
8 function calls in 40.473 seconds
Ordered by: call count, name/file/line
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 40.473 40.473 <string>:1(<module>)
1 0.000 0.000 40.473 40.473 test.py:31(run_tests)
1 10.466 10.466 10.466 10.466 test.py:6(test1)
1 7.475 7.475 7.475 7.475 test.py:11(test2)
1 7.485 7.485 7.485 7.485 test.py:16(test3)
1 7.539 7.539 7.539 7.539 test.py:21(test4)
1 7.508 7.508 7.508 7.508 test.py:26(test5)
using65536
最慢,为 10.466 秒,而 doing256**2
最快,为 7.475 秒(其他可能的指数值介于两者之间)。诚然,这种速度差异只有在大量重复的情况下才会明显,但我仍然很好奇为什么会发生这种情况。
为什么取模数65536
比使用指数取模要慢?它们应该评估为相同的数字,我原以为 python 解释器在使用 mod 之前需要更长的时间来完全评估指数。
通过扩展,在python表达式中使用2的幂而不是完全输入数字通常更有效吗?这种模式是否适用于除模数以外的运算或除 以外的其他数字2
吗?
(顺便说一句,我使用的是 Python 2.7.2(32 位),并且我在 64 位 Windows 7 笔记本电脑上运行了上述程序)。
编辑:
所以我尝试颠倒我调用的函数的顺序,现在正好相反。看起来run_tests
在使用 cProfile 时,无论第一个函数是什么,运行速度总是会慢一些,这很奇怪。所以,吸取教训,我猜——分析器很奇怪:D