Ich habe mir die Quelle der sortierten Container angesehen und war überrascht, diese Zeile zu sehen :
self._load, self._twice, self._half = load, load * 2, load >> 1
Hier load
ist eine ganze Zahl. Warum Bitverschiebung an einer Stelle und Multiplikation an einer anderen verwenden? Es erscheint vernünftig, dass die Bitverschiebung schneller ist als die integrale Division durch 2, aber warum nicht auch die Multiplikation durch eine Verschiebung ersetzen? Ich habe die folgenden Fälle verglichen:
- (Zeiten teilen)
- (Verschiebung, Verschiebung)
- (Zeiten, Verschiebung)
- (verschieben, teilen)
und festgestellt, dass # 3 durchweg schneller ist als andere Alternativen:
# 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)])
Die Frage:
Ist mein Test gültig? Wenn ja, warum ist (multiplizieren, verschieben) schneller als (verschieben, verschieben)?
Ich führe Python 3.5 unter Ubuntu 14.04 aus.
Bearbeiten
Oben ist die ursprüngliche Aussage der Frage. Dan Getz liefert in seiner Antwort eine hervorragende Erklärung.
Der Vollständigkeit halber finden Sie hier Beispielabbildungen für größere, x
wenn Multiplikationsoptimierungen nicht zutreffen.
x
sei denn, es ist sehr groß, denn das ist nur eine Frage, wie es im Speicher gespeichert ist, oder?
x
?