6

平均而言,我可以合理地期望perform:比发送文字消息慢多少?我是否应该避免perform:在循环中发送,类似于对 Perl/Python 程序员的警告,以避免在循环中调用eval("...")Compiler evaluate:在 Smalltalk 中)?

我主要关心 Squeak,但也对其他 Smalltalks 感兴趣。此外,perform:with:变体的开销是否更大?谢谢

4

2 回答 2

9

#perform:不像eval()。(无论如何,在性能方面)的问题eval()在于它必须编译您在运行时发送的代码,这是一个非常缓慢的操作。#perform:另一方面,Smalltalk等价于 Rubysend()或 Objective-C performSelector:(事实上,这两种语言都深受 Smalltalk 的启发)。像这样的语言已经根据它们的名称查找方法——#perform:只允许您在运行时而不是在写入时指定名称。它不必解析任何语法或编译任何类似eval().

它会慢一点(至少一个额外的方法调用的成本),但它不像eval(). 此外,具有更多参数的变体不应该显示速度与简单的任何差异perform:whatever。我不能专门谈论关于 Squeak 的太多经验,但这就是它通常的工作方式。

于 2009-05-07T23:57:05.223 回答
3

这是我机器上的一些数字(它是 Smalltalk/X,但我想这些数字是可比的——至少比率应该是):

被调用的方法 "foo" 和 "foo:" 是一个 noops(即由一个 ^self 组成):

self foo                               ...  3.2 ns
self perform:#foo                      ...  3.3 ns
[self foo] value                       ... 12.5 ns (2 sends and 2 contexts)
[ ] value                              ...  3.1 ns (empty block)
Compiler valuate:('TestClass foo')     ...  1.15 ms

self foo:123                           ...  3.3 ns
self perform:#foo: with:123            ...  3.6 ns
[self foo:123] value                   ...   15 ns (2 sends and 2 contexts)
[self foo:arg] value:123               ...   23 ns (2 sends and 2 contexts)
Compiler valuate:('TestClass foo:123') ...  1.16 ms

注意“执行:”和“评估:”之间的巨大区别;评估是调用编译器来解析字符串,生成一个丢弃的方法(字节码),执行它(它在第一次调用时被jited)并最终被丢弃。编译器实际上主要用于 IDE 并从外部流中归档代码;它具有用于错误报告、警告消息等的代码。通常,当性能至关重要时,eval 不是您想要的。

来自戴尔 Vostro 的计时;您的里程可能会有所不同,但比率不会。我试图通过测量空循环时间并减去来获得净执行时间;此外,我运行了 10 次测试并利用了最好的时间,以消除操作系统/网络/磁盘/电子邮件或任何干扰。但是,我并不真正关心无负载机器。测量代码是(用上面的东西替换了第二次重复参数):

callFoo2
    |t1 t2|

    t1 :=
        TimeDuration toRun:[
            100000000 timesRepeat:[]
        ].

    t2 :=
        TimeDuration toRun:[
            100000000 timesRepeat:[self foo:123]
        ].

    Transcript showCR:t2-t1

编辑: PS:我忘了提:这些是 IDE 内部的时间(即字节码抖动执行)。由于更好的寄存器分配算法,静态编译的代码(使用 stc 编译器)在这些低级微基准测试中通常会更快一些(20-30%)。

编辑:前几天我试图重现这些数字,但得到了完全不同的结果(简单调用为 8ns,而执行为 9ns)。所以要非常小心这些微定时,因为它们完全耗尽了一级缓存(空消息甚至会忽略上下文设置,或者被内联)——它们通常不能很好地代表整体性能。

于 2010-08-25T12:34:52.830 回答