我有一些python脚本花费的时间比我预期的要长,所以我开始调查并发现python的性能有一些令人惊讶的地方。大多数情况下,它似乎围绕着reduce
展开,但我不明白为什么。在
为了进行实验,我编写了以下两个模块:
py.py
from functools import reduce
def mysum(n):
return reduce(lambda acc, x: acc + x, range(n + 1))
n = int(1e8)
print(mysum(n))
以及
clj.clj
我用time
比较了他们的表现:
➜ ~ time python py.py
5000000050000000
python py.py 21.90s user 0.41s system 95% cpu 23.344 total
➜ ~ time lumo clj.clj
5000000050000000
lumo clj.clj 2.44s user 0.13s system 102% cpu 2.519 total
python的执行速度似乎比clojure实现慢10倍以上。但这与我的预期正好相反。在
即使在使用JVM运行clj文件时(这会导致大量的启动成本),python也会被远远击败:
➜ ~ time clj clj.clj
5000000050000000
clj clj.clj 6.01s user 0.72s system 153% cpu 4.394 total
为什么python的reduce在这里这么慢?我做错什么了吗?在
我记得,range生成一个列表,而xrange生成iterable。尽管如此,我试着更换它,但没用。所以,是的,这里的关键问题似乎与口译员的本性有关。 顺便说一下,这个很快就好了- 总和(X范围(10000001))
您的python代码正在被解释,而Clojure代码是由HotSpot编译器在JVM上编译的。这是JVM上的一大优势,也是Python&Ruby在JVM上分别有Jython和JRuby端口的原因。在
简单求和在原生Java中甚至更快:下面是一些快速比较:
是的,这是66倍的加速。尝试将计数减少到
^{pr2}$1e6
。在另一个诀窍是Hotspot编译器通常可以识别1..N中的和并在代数公式中进行替换
根本没有循环!在
相关问题 更多 >
编程相关推荐