value = i % 65536
いじくり回しているプログラムを最適化しようとしていたとき、実行が実行よりも遅いように見えることに気付きました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 秒で最も遅く、doing は 7.475 秒で256**2
最も高速でした (他の可能な指数値はその間にあります)。確かに、この速度の違いは、繰り返し回数が多い場合にのみ顕著になりますが、なぜこれが発生するのかについてはまだ興味があります.
65536
指数を使用して mod を取得するよりも、数値の mod を取得する方が遅いのはなぜですか? それらは同じ数値に評価されるはずであり、mod を使用する前に Python インタープリターが指数を完全に評価するには時間がかかると思っていたでしょう。
拡張により、数値を完全に入力するよりも、python 式で 2 の累乗を使用する方が一般的に効率的ですか? また、このパターンは、モジュラス以外の演算や 以外の数値にも当てはまります2
か?
(ところで、私はPython 2.7.2(32ビット)を使用しており、64ビットのWindows 7ラップトップで上記を実行しました)。
編集:
だから私は呼び出す関数の順序を逆にしてみましたが、今は逆です。run_tests
cProfile を使用すると、最初の関数の実行速度が常に少し遅くなるように見えますが、これは奇妙なことです。だから、学んだ教訓は、私が推測する - プロファイラーは奇妙です:D