为啥 x*=y 在 Python 中比 x=x*y 慢?

Posted

技术标签:

【中文标题】为啥 x*=y 在 Python 中比 x=x*y 慢?【英文标题】: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 【参考方案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__ 多余的两个参数进行了一些检查。

以上是关于为啥 x*=y 在 Python 中比 x=x*y 慢?的主要内容,如果未能解决你的问题,请参考以下文章

随机变量X,Y独立,则X²与Y²,X与Y²,X²与Y,等等为啥为啥都独立?

每日一题39. Contest(树状数组 / 容斥分治)

为啥这个 python 程序有以下输出?

x,y 都是int, x++=y++ 为啥错?

为啥我们在 Scikit learn 中将 X_test 存储到 y_preds 变量中? [关闭]

为啥这段代码在 for 循环中只使用 x 而不是 x 和 y? [关闭]