Jas*_*n P 21 python optimization python-internals
我知道这可能被认为是一个非问题,但我为HPC环境编写软件,所以这3.5倍的速度增加实际上有所不同.
In [1]: %timeit 10 / float(98765)
1000000 loops, best of 3: 313 ns per loop
In [2]: %timeit 10 / (98765 * 1.0)
10000000 loops, best of 3: 80.6 ns per loop
Run Code Online (Sandbox Code Playgroud)
我曾经dis看过代码,我认为它float()会变慢,因为它需要一个函数调用(不幸的是我无法dis.dis(float)看到它实际上在做什么).
我想第二个问题是我float(n)应该何时使用,何时使用n * 1.0?
the*_*eye 28
因为Peep孔优化器通过预先计算乘法的结果来优化它
import dis
dis.dis(compile("10 / float(98765)", "<string>", "eval"))
1 0 LOAD_CONST 0 (10)
3 LOAD_NAME 0 (float)
6 LOAD_CONST 1 (98765)
9 CALL_FUNCTION 1
12 BINARY_DIVIDE
13 RETURN_VALUE
dis.dis(compile("10 / (98765 * 1.0)", "<string>", "eval"))
1 0 LOAD_CONST 0 (10)
3 LOAD_CONST 3 (98765.0)
6 BINARY_DIVIDE
7 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
它将98765 * 1.0字节码中的结果存储为常量值.因此,它只需要加载它并进行除法,就像在第一种情况下我们必须调用函数一样.
我们可以更清楚地看到这一点
print compile("10 / (98765 * 1.0)", "<string>", "eval").co_consts
# (10, 98765, 1.0, 98765.0)
Run Code Online (Sandbox Code Playgroud)
由于该值是在编译时自身预先计算的,因此第二个更快.
编辑:正如Davidmh在评论中指出的那样,
而且它之所以没有优化掉除法的原因是因为它的行为依赖于旗帜,
from __future__ import division也因为-Q旗帜.
/* Cannot fold this operation statically since
the result can depend on the run-time presence
of the -Qnew flag */
Run Code Online (Sandbox Code Playgroud)