为什么在Python 3.11中使用random.random的这段特定代码比在Python 3.10.6中运行得更慢?

3

我很想听听其他人对这段代码为什么在 Python 3.11 上运行速度比 Python 3.10.6 慢的想法。此帖已经分贴自 这里我是新手 - 如果我做错了什么,请好心告诉我。

test.py 脚本:

import timeit
from random import random


def run():
    for i in range(100):
        j = random()


t = timeit.timeit(run, number=1000000)
print(t)

命令:

(base) conda activate python_3_10_6

(python_3_10_6) python test.py
5.0430680999998

(python_3_10_6) conda activate python_3_11

(python_3_11) python test.py
5.801756700006081

1
这是一个特性。代码执行取决于许多因素。传递给处理器的指令数量会根据其可用性而变化。如果您一遍又一遍地运行相同的代码,甚至可以观察到不同的时间持续时间。可以预期微秒级别的延迟。 - Bhargav - Retarded Skills
2
Andrew:好的。如果这种交叉发布方式不被认为是可接受的,请告诉我,我会删除帖子/问题。Bhargav:关于运行之间的小差异,我已经尝试使用两个版本的Python多次运行脚本,并始终发现3.11在运行此特定脚本时略微慢一些。我意识到在实际情况下这只是微小的差别。更一般地说,我确实知道Python 3.11根据开发人员的说法更快并不意味着所有脚本都会运行得更快。 - mh0w
3
很有趣。我得到了类似的结果。当我第一次获得3.11并阅读它更快时,我在3.10上运行了一个包含超过1亿次模幂运算的算法,但没有观察到任何加速(尽管在那种情况下我也没有观察到任何减速)。 - John Coleman
1
如果您想这样跨贴,请在元社区上询问是否可以。在多个Stack Exchange社区上进行交叉发布肯定是不可以的,但Reddit并不是Stack Exchange社区。 - John Coleman
1
首先,为什么人们会反对在 Reddit 上进行跨贴?这不是一个跨帖通知,而是“我在 Reddit 上问了这个问题”。在我看来,没有必要进行元提问。其次,了解性能如何工作非常适合在这里进行软件开发的主题,因此关闭投票是不合理的。这个网站上最受欢迎的 Q 是什么?它与这个问题有什么实质性的不同吗?第三,答案中提供了很好的信息,这使得这个问题很有可能是一个好问题。 - JL Peyret
显示剩余3条评论
1个回答

7
这似乎可能是PEP 659优化random.random无效的结果。
PEP 659旨在JIT优化许多常见操作。(不是JIT编译,但肯定是JIT优化。)它对大多数Python代码都很有效,但我认为random.random没有被覆盖。

random.random 是一个方法(隶属于隐藏的random.Random实例),用C语言编写,除了self之外没有其他参数,因此它应该使用 METH_NOARGS 调用约定。这个调用约定没有专门的快速路径。specialize_c_call_Py_Specialize_Call 都只是放弃而不是对调用进行专门化。

当PEP 659无法产生回报时,支持它所需的工作只是额外开销。我不确定哪些部分贡献了多少开销,但字节码比以前更长,因为生成了PRECALLCALL指令(尽管我认为有一些改进正在进行中),另外尝试专门化和跟踪何时尝试专门化也有自己的开销。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接