Skip to main content
 首页 » 编程设计

python之Python 会自动用 1 替换 * 2 吗

2025年05月04日10itcoder

我看到一些建议(请参阅 Is multiplication and division using shift operators in C actually faster?),您不应手动将乘法替换为移位运算符,因为编译器必须自动执行此操作,而移位运算符会降低可读性。我写了一个简单的测试来检查这个:

import numpy as np 
import time 
 
array1 = np.random.randint(size=10 ** 6, low=0, high=10 ** 5) 
array2 = np.zeros((10 ** 6,), dtype=np.int) 
 
total = 0.0 
for i in range(100): 
    start = time.clock() 
    for j in range(len(array2)): 
        array2[j] = array1[j] * 2 
    total += time.clock() - start 
print("*2 time = " + str(round(total / 10, 5)) + " ms") 
 
 
total = 0.0 
for i in range(100): 
    start = time.clock() 
    for j in range(len(array2)): 
        array2[j] = array1[j] << 1 
    total += time.clock() - start 
print("<< 1 time = " + str(round(total / 10, 5)) + " ms") 
 
 
total = 0.0 
for i in range(100): 
    start = time.clock() 
    for j in range(len(array2)): 
        array2[j] = array1[j] // 2 
    total += time.clock() - start 
print("//2 time = " + str(round(total / 10, 5)) + " ms") 
 
 
total = 0.0 
for i in range(100): 
    start = time.clock() 
    for j in range(len(array2)): 
        array2[j] = array1[j] >> 1 
    total += time.clock() - start 
print(">> 1 time = " + str(round(total / 10, 5)) + " ms") 

我使用了等效操作(* 2 等效于 << 1 和 // 2 等效于 >> 1),结果如下:

*2 time = 5.15086 ms 
<< 1 time = 4.76214 ms 
//2 time = 5.17429 ms 
>> 1 time = 4.79294 ms 

怎么了?我的测试方法错了吗?时间测量有误吗?还是 Python 不执行此类优化(如果是,我应该害怕那个)?我在 Win 8.1 x64 上使用了 cPython 3.4.2 x64。

请您参考如下方法:

这种优化不会发生在字节码级别:

>>> import dis 
>>> dis.dis(lambda x: x*2) 
  1           0 LOAD_FAST                0 (x) 
              3 LOAD_CONST               1 (2) 
              6 BINARY_MULTIPLY 
              7 RETURN_VALUE 
>>> dis.dis(lambda x: x<<1) 
  1           0 LOAD_FAST                0 (x) 
              3 LOAD_CONST               1 (1) 
              6 BINARY_LSHIFT 
              7 RETURN_VALUE 

dis模块允许你向你展示当你的代码被执行时“内部”Python 发生了什么,或者更准确地说,到底执行了什么。输出显示 *运算符映射到 BINARY_MULTIPLY和 <<运算符映射到 BINARY_LSHIFT .这两个字节码操作是用C语言实现的。