私はsorted_containersのソースを見ていて、この行を見て驚いた:
self._load, self._twice, self._half = load, load * 2, load >> 1
これload
は整数です。ある場所でビットシフトを使用し、別の場所で乗算を使用するのはなぜですか?2による整数除算よりもビットシフトの方が速い場合があるのは理にかなっていますが、乗算もシフトで置き換えてみませんか?私は以下のケースをベンチマークしました:
- (回、除算)
- (シフト、シフト)
- (回、シフト)
- (シフト、除算)
そして#3は他の選択肢よりも一貫して速いことがわかりました:
# self._load, self._twice, self._half = load, load * 2, load >> 1
import random
import timeit
import pandas as pd
x = random.randint(10 ** 3, 10 ** 6)
def test_naive():
a, b, c = x, 2 * x, x // 2
def test_shift():
a, b, c = x, x << 1, x >> 1
def test_mixed():
a, b, c = x, x * 2, x >> 1
def test_mixed_swapped():
a, b, c = x, x << 1, x // 2
def observe(k):
print(k)
return {
'naive': timeit.timeit(test_naive),
'shift': timeit.timeit(test_shift),
'mixed': timeit.timeit(test_mixed),
'mixed_swapped': timeit.timeit(test_mixed_swapped),
}
def get_observations():
return pd.DataFrame([observe(k) for k in range(100)])
質問:
テストは有効ですか?もしそうなら、なぜ(乗算、シフト)が(シフト、シフト)より速いのですか?
Ubuntu 14.04でPython 3.5を実行しています。
編集する
上記は、質問の元のステートメントです。ダンゲッツは彼の答えで優れた説明を提供します。
完全を期すために、ここではx
、乗算の最適化が適用されない場合の大規模なサンプル図を示します。
x
非常に大きくない限り、それは操作とは無関係であると期待します。
x
か?