就速度而言,Pharo与Python3相比如何?

就速度而言,Pharo与Python3相比如何?,python,performance,benchmarking,smalltalk,pharo,Python,Performance,Benchmarking,Smalltalk,Pharo,我在编程方面没有太多经验,但我知道一点Python 3,现在我正在学习Pharo。我仍然不熟悉面向对象编程或类浏览器,但我已经阅读了ProfStef教程,我正在操场上玩小程序,以熟悉语法 我首先好奇的是,当我在某处读到Pharo内置了JIT编译器时,这两种语言在速度方面的比较。所以我用两种语言编写了一个奇怪的脚本,生成800万个数字,过滤其中的1/3,计算每个数字的1/sqrt(x),对结果求和,并将这个过程重复100次,每次稍微改变间隔,最后再次对结果求和,并对整个过程进行计时。这不是一个合适

我在编程方面没有太多经验,但我知道一点Python 3,现在我正在学习Pharo。我仍然不熟悉面向对象编程或类浏览器,但我已经阅读了ProfStef教程,我正在操场上玩小程序,以熟悉语法

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

Python 3版本:

导入时间、数学
mega=lambda n:sum([1/math.sqrt(1+i+n)表示范围(8000000)内的i,如果(i+1)//3==0])
开始=时间。时间()
打印(总和([mega(n+1)表示范围内的n(100)])
停止=时间。时间()-开始
打印(停止)
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%。所以我猜它们的速度大约是相同的数量级。这是典型的情况吗?

这种测试说明不了什么。主要原因是大部分计算都是重复地将相同的消息发送给相同类的实例(
quo:
=
对于
选择:
/
+
收集:
中的
sqrt
等)。这意味着像方法查找这样耗时的(内部)操作只发生一次,然后被困在内联缓存中。因此,在运行这些基准测试时,您可能会有一个比另一个更好的系统,而在运行“真正”的应用程序时,这个系统会慢得多。除了减少方法查找需求的(单缓存或多态缓存)内联缓存外,其他技术也有不同之处,如垃圾收集器的性能、方法内联(用目标代码的副本替换发送站点)、寄存器分配(用于最小化内存访问)、变为:消息的性能、,多种因素使得我们需要测量更复杂的代码片段,尝试使用我刚才提到的已知瓶颈。有时,一个小小的改变可能会暴露出系统中隐藏的优点(或缺点)。因此,我的建议是,在进行此类分析时,你应该更加努力,设计测试,旨在测量系统对特定压力的反应。

虽然还不是惯用的闲话

| 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倍。这一点突出了莱安德罗的观点。

谢谢你的解释。我想在我能够设计出合适的测试之前,我需要一段时间来摸索这门语言。正如其他人以前可能做过的那样,我只是问。我在我的机器上运行了你的版本,事实上只花了19秒。给人印象深刻的非常感谢。