これが私のマシンからのいくつかの数値です(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
「perform:」と「evaluate:」の大きな違いに注意してください。Evaluationは、コンパイラを呼び出して文字列を解析し、スローアウェイメソッド(バイトコード)を生成して実行し(最初の呼び出しで変更されます)、最後に破棄されます。コンパイラは実際には、主にIDEと外部ストリームからのfileInコードに使用されるように作成されています。エラー報告、警告メッセージなどのコードが含まれています。一般に、パフォーマンスが重要な場合、evalは必要なものではありません。
DellVostroからのタイミング。あなたのマイレージは変わるかもしれませんが、比率は変わりません。空のループ時間を測定して減算することにより、正味の実行時間を取得しようとしました。また、OS /ネットワーク/ディスク/電子メールなどの障害を排除するために、テストを10回実行し、最善の時間を費やしました。しかし、私は無負荷のマシンをあまり気にしませんでした。メジャーコードは次のとおりです(2回目のRepeat-argを上記のものに置き換えました):
callFoo2
|t1 t2|
t1 :=
TimeDuration toRun:[
100000000 timesRepeat:[]
].
t2 :=
TimeDuration toRun:[
100000000 timesRepeat:[self foo:123]
].
Transcript showCR:t2-t1
編集:PS:言及するのを忘れました:これらはIDE内からの時間です(つまり、バイトコードで実行されます)。静的にコンパイルされたコード(stc-compilerを使用)は、レジスタ割り当てアルゴリズムが優れているため、これらの低レベルのマイクロベンチマークでは一般に少し高速(20〜30%)になります。
編集:先日、これらの数値を再現しようとしましたが、まったく異なる結果が得られました(単純な呼び出しでは8ns、実行では9ns)。したがって、これらのマイクロタイミングは第1レベルのキャッシュを完全に使い果たしてしまうため、十分に注意してください(空のメッセージでは、コンテキストセットアップが省略されたり、インライン化されたりします)。通常、これらは全体的なパフォーマンスをあまり表していないためです。