Boy*_*lev 8 python operators translate
换句话说,两个星号背后是什么?它只是将数字乘以x倍或其他?作为后续问题,写2**3或2*2*2是否更好.我问,因为我听说在C++中最好不要使用pow()进行简单的计算,因为它调用了一个函数.
如果你对内部感兴趣,我会反汇编指令以获取它映射到的CPython字节码.使用Python3:
»»» def test():
return 2**3
...:
»»» dis.dis(test)
2 0 LOAD_CONST 3 (8)
3 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
好的,所以似乎在进入时已经完成了计算,并存储了结果.您获得2*2*2的完全相同的CPython字节码(随意尝试).因此,对于求值为常量的表达式,您得到相同的结果,并不重要.
如果你想要一个变量的力量怎么办?
现在你得到两个不同的字节码:
»»» def test(n):
return n ** 3
»»» dis.dis(test)
2 0 LOAD_FAST 0 (n)
3 LOAD_CONST 1 (3)
6 BINARY_POWER
7 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
与
»»» def test(n):
return n * 2 * 2
....:
»»» dis.dis(test)
2 0 LOAD_FAST 0 (n)
3 LOAD_CONST 1 (2)
6 BINARY_MULTIPLY
7 LOAD_CONST 1 (2)
10 BINARY_MULTIPLY
11 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
现在的问题当然是BINARY_MULTIPLY比BINARY_POWER操作更快吗?
尝试这种方法的最佳方法是使用timeit.我将使用IPython %timeit魔法.这是乘法的输出:
%timeit test(100)
The slowest run took 15.52 times longer than the fastest. This could mean that an intermediate result is being cached
10000000 loops, best of 3: 163 ns per loop
Run Code Online (Sandbox Code Playgroud)
并为权力
The slowest run took 5.44 times longer than the fastest. This could mean that an intermediate result is being cached
1000000 loops, best of 3: 473 ns per loop
Run Code Online (Sandbox Code Playgroud)
您可能希望对代表性输入重复此操作,但凭经验看,乘法更快(但请注意所提到的关于输出方差的警告).
如果你想进一步的内部,我建议深入研究CPython代码.
虽然第二个对于数字来说稍微快一点,但与第一个相比,优势非常低:可读性。如果您需要时间,并且您面临进行此类优化的压力,那么 python 可能不是您应该使用的语言。
注意:对于数字以外的值:
a ** b翻译为
a.__pow__(b)
Run Code Online (Sandbox Code Playgroud)
而a * a * a是对
a.__mul__(a.__mul__(a))
Run Code Online (Sandbox Code Playgroud)
import time
s = time.time()
for x in xrange(1,1000000):
x**5
print "done in ", time.time() - s
s = time.time()
for x in xrange(1,1000000):
x*x*x*x*x
print "done in ", time.time() - s
Run Code Online (Sandbox Code Playgroud)
对于我的机器,它产生:
done in 0.975429058075
done in 0.260419845581
[Finished in 1.2s]
Run Code Online (Sandbox Code Playgroud)