在速度方面,Pharo 与 Python3 相比如何?

Speedwise, how does Pharo compare to Python3?

提问人:kleite 提问时间:12/13/2020 最后编辑:mkrieger1kleite 更新时间:12/19/2020 访问量:970

问:

我在编程方面没有太多经验,但我对 Python3 略知一二,现在我正在迈出学习 Pharo 的第一步。我仍然不熟悉面向对象编程或类浏览器,但我已经阅读了 ProfStef 教程,并且正在 Playground 上玩小程序,以熟悉语法。

我好奇的第一件事是这两种语言在速度方面的比较,因为我在某处读到Pharo内置了一个JIT编译器。于是我用两种语言写了一个异想天开的小脚本,生成了 800 万个数字,过滤了其中的 1/3,为每个数字计算 1/sqrt(x),对结果求和,然后重复这个过程一百次,每次稍微改变间隔,最后再次对结果求和,并对整个过程进行计时。不是一个合适的基准,只是一个获得数量级估计的练习,但我试图让两个版本尽可能相似。

Python 3 版本:

import time, math

mega = lambda n: sum([1/math.sqrt(1 + i + n) for i in range(8000000) if (i + 1) // 3 == 0])
start = time.time()
print(sum([mega(n + 1) for n in range(100)]))
stop = time.time() - start
print(stop)

Python 3.8.5 的结果(默认,2020 年 7 月 28 日 12:59:40):

34.7701230607214
52.75216603279114

Pharo 8 版本:

| mega range start stop |.

range := [:n | (((1 to: 8000000) select: [:j | (j quo: 3) = 0]) collect: [:i | 1 / (n + i) sqrt]) sum].
start := DateAndTime  now.
Transcript show: (((1 to: 100) collect: [:n | range value: n]) sum); cr.
stop := (DateAndTime now - start) asSeconds.
Transcript show: stop; cr.

Pharo-8.0.0+build.1141.sha.1b7a8d8203fce2a57794451f555bba4222614081(64 位)的结果:

34.7701230607214
45

正如我所料,Pharo 版本运行得更快,但幅度不大,为 45 秒,而 Python 则为 52 秒多一点。花费的时间减少了约 13%。所以我想它们的速度大约是相同的数量级。这是典型的情况吗?

Python 性能 基准测试 Smalltalk Pharo

评论


答:

8赞 Leandro Caniglia 12/13/2020 #1

这种测试并不能说明什么。主要原因是大部分计算包括重复向相同类的实例发送相同的消息(以及 和 、 、 等)。这意味着耗时的(内部)操作(如方法查找)只发生一次,然后被困在内联缓存中。因此,在运行这些基准测试时,您的系统性能可能优于另一个系统,而在运行“真实”应用程序时速度要慢得多。除了(单态或多态)内联缓存(减少方法查找的需要)之外,其他不同的技术是垃圾回收器的性能、方法内联(用目标代码的副本替换发送站点)、寄存器分配(用于最小化内存访问)、消息的性能等。由于因素众多,因此需要测量更复杂的代码片段,并尝试像我刚才提到的那样练习已知的瓶颈。有时,一个小小的改变可能会暴露出系统隐藏的优势(或劣势)。因此,我的建议是,在进行这种分析时,您应该更加努力地设计测试,以测量系统如何响应特定类型的压力。quo:=select:/+sqrtcollect:become:

评论

0赞 kleite 12/13/2020
谢谢你的解释。我认为在我能够设计适当的测试之前,我需要一些时间来摸索语言。就像其他人以前可能做过的那样,我只是问。
3赞 Stephan Eggermont 12/19/2020 #2

虽然仍然不是那么惯用的闲聊,

| range start stop |.

range := [ :n | (1 to: 8000000) inject: 0 into: [:sum :in | 
    ((in quo: 3) = 0 )
        ifTrue: [1 / ( n + in) sqrt + sum] 
        ifFalse: [sum]]].
start := DateAndTime  now.
Transcript show: (((1 to: 100) collect: [:n | range value: n]) sum); cr.
stop := (DateAndTime now - start) asSeconds.
Transcript show: stop; cr.

速度快 2.5 倍。这在某种程度上强调了莱安德罗的观点。

评论

0赞 kleite 12/20/2020
我在我的机器上运行了你的版本,实际上只花了 19 秒。令人 印象 深刻!谢谢。