【发布时间】:2016-08-31 09:44:01
【问题描述】:
我在看sorted_containers的来源,惊讶地看到this line:
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)])
问题:
我的测试有效吗?如果是,为什么 (multiply, shift) 比 (shift, shift) 快?
我在 Ubuntu 14.04 上运行 Python 3.5。
编辑
以上是问题的原始陈述。 Dan Getz 在他的回答中提供了很好的解释。
为了完整起见,这里是不适用乘法优化时较大的x 的示例插图。
【问题讨论】:
-
你在哪里定义
x? -
我真的很想看看使用小端/大端是否有任何区别。真的很酷的问题顺便说一句!
-
@LiGhTx117 我希望这与操作无关,除非
x非常大,因为这只是它如何存储在内存中的问题,对吧? -
我很好奇,乘以 0.5 而不是除以 2 怎么样?根据以前使用 mips 汇编编程的经验,除法通常会导致乘法运算。 (这将解释移位而不是除法的偏好)
-
@Sayse 会将其转换为浮点数。希望整数地板除法会比通过浮点往返更快。
标签: python python-3.x performance bit-shift integer-arithmetic