【问题标题】:Why is x*=y is slower than x=x*y in Python?为什么 x*=y 在 Python 中比 x=x*y 慢?
【发布时间】:2020-06-26 12:02:23
【问题描述】:

我正在尝试优化我用 Python 编写的一些代码,并且自始至终我都认为在 Python 中编写 x *= y 而不是 x = x * y 更有效(或者在最坏的情况下等效)。但是使用以下基本测试似乎并非如此

import time

t0 = time.time()
x = 1.01
for i in range(1000000):
    x *= 1.000001
print(time.time() - t0)
# Outputs 0.1081240177154541

t0 = time.time()
x = 1.01
for i in range(1000000):
    x = x * 1.000001
print(time.time() - t0)
# Outputs 0.07818889617919922

为什么会这样?

【问题讨论】:

  • 将循环量乘以10并运行测试几次,您会发现时间几乎相同
  • 当我运行这个时,时间相差不到万分之一。我建议使用更可靠的方法,例如timeit
  • 补充一点:use 可以在 jupyter notebook 中使用 timeit 并指定运行次数和每次运行的循环次数。例如,10 次运行,每次 10 次循环:%%timeit -r 10 -n 10

标签: python performance assignment-operator


【解决方案1】:

我一直在做休闲测试:

def test1(x):
    for i in range(10000000):
        x *= 1.000001

def test2(x):
    for i in range(10000000):
        x = x * 1.000001


%timeit test1(1.01)
# 511 ms ± 25.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit test2(1.01)
# 591 ms ± 87.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

差别小到可以说性能是一样的

正如我的结果所示(与您的结论相反),结果可能因一台机器而异,或从一次运行到另一台机器不同

【讨论】:

  • 谢谢。你究竟是如何使用 timeit 来产生这个输出的?
  • 我在使用 python 3.7 的 jupyter notebook 中使用timeit,从一次运行到另一次运行结果不一样
  • 你可以在 IDLE 中这样做吗?
  • 我不会将 15% 的平均加速称为特别小,尤其是对于这种低级别的东西。
  • 我的猜测是float.__rmul__ 在后台做了一些额外的工作,尽管我无法从源头上确定它。例如,x *= 1jx 从浮点数变为复数(并更改 id(x))。所以大概float.__rmul__float.__mul__ 多余的两个参数进行了一些检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-25
  • 2019-05-13
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
  • 2011-01-17
  • 1970-01-01
相关资源
最近更新 更多