4

从纯粹的性能角度来看,将重复算术运算的结果分配给变量并在整个代码中使用该变量通常是最佳实践吗?或者 Python 是否有一些内部方法来缓存结果并在遇到重复语句时使用它。

例如,这是否更有效:

a = 50
b = a*12-1
c = a*b

print c
#some code
print c*100 + 10
#some code
print c/100 + 20
#etc

比这个:

print 50*(50*12-1)
#some code
print 50*(50*12-1) * 100 + 10
#some code
print 50*(50*12-1) / 100 + 20
#etc
4

3 回答 3

7

我不知道任何缓存中间结果的 Python 实现。绑定一个局部变量非常便宜,所以经过几次计算,它会更快。

在仅使用常量的特殊情况下,窥视孔优化器可以将其减少为常量

例如。

$ python3.3
Python 3.3.0 (default, Sep 29 2012, 17:17:45) 
[GCC 4.7.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def x():
...     50*(50*12-1)
...     50*(50*12-1) * 100 + 10
...     50*(50*12-1) / 100 + 20
... 
>>> dis.dis(x)
  2           0 LOAD_CONST               9 (29950) 
              3 POP_TOP              

  3           4 LOAD_CONST              14 (2995010) 
              7 POP_TOP              

  4           8 LOAD_CONST              19 (319.5) 
             11 POP_TOP              
             12 LOAD_CONST               0 (None) 
             15 RETURN_VALUE         

如果有疑问,请选择可读版本。如果您真的需要那些额外的微秒,则进行微优化

于 2013-07-23T00:56:35.720 回答
2

对我来说,这似乎是一个可以忽略不计的速度:

> python -m timeit 'a = 50; b = a*12-1; c = a*b; c; c*100+10; c/100+20;'
1000000 loops, best of 3: 0.27 usec per loop
> python -m timeit '50*(50*12-1); 50*(50*12-1) * 100 + 10; 50*(50*12-1) / 100 + 20'
1000000 loops, best of 3: 0.218 usec per loop

赋值比不断重新计算要慢一些,但正如 korylprince 在评论中所说,赋值将使代码更易于阅读。

编辑:我认为这是 gnibbler 在评论中的意思,但它仍然较慢:

> python -m timeit 'def x(): a = 50; b = a*12-1; c = a*b; c; c*100+10; c/100+20;' 'x()'
1000000 loops, best of 3: 0.428 usec per loop

edit2:这实际上是gnibbler在评论中的意思,差异仍然可以忽略不计。关于使用更具可读性的评论仍然成立:

> python -m timeit -s 'def x(): a = 50; b = a*12-1; c = a*b; c; c*100+10; c/100+20;' 'x()'
1000000 loops, best of 3: 0.367 usec per loop
> python -m timeit -s 'def x(): 50*(50*12-1); 50*(50*12-1) * 100 + 10; 50*(50*12-1) / 100 + 20' 'x()'
1000000 loops, best of 3: 0.278 usec per loop
于 2013-07-23T00:56:18.450 回答
0

文字会更快,因为它不必引用任何东西。Python 中没有预处理,所以你不能像在 C 中那样做 #define。

于 2013-07-23T00:47:32.483 回答