Voici quelques chiffres de ma machine (il est Smalltalk/X, mais je suppose que les chiffres sont comparables - au moins les rapports devraient être):
Les méthodes dites « foo » et « foo: » sont un noops (ie consistent en un^auto):
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
Notez la grande différence entre "effectuer:" et "évaluer"; evaluate appelle le compilateur pour analyser la chaîne, générer une méthode throw-away (bytecode), l'exécuter (il est jeté lors du premier appel) et finalement rejeté. Le compilateur est en fait écrit pour être utilisé principalement pour l'IDE et pour le code fileIn de flux externes; Il a un code pour les rapports d'erreurs, les messages d'avertissement, etc. En général, eval n'est pas ce que vous voulez quand les performances sont critiques.
Délais d'un Dell Vostro; votre kilométrage peut varier, mais pas les ratios. J'ai essayé d'obtenir les temps d'exécution du réseau, en mesurant le temps de boucle vide et en soustrayant; aussi, j'ai couru les tests 10 fois et pris les meilleurs temps, pour éliminer OS/réseau/disque/e-mail ou autres perturbations. Cependant, je ne me souciais pas vraiment d'une machine sans charge. Le code de mesure a été (a remplacé le deuxième timesRepeat-arg avec les choses ci-dessus):
callFoo2
|t1 t2|
t1 :=
TimeDuration toRun:[
100000000 timesRepeat:[]
].
t2 :=
TimeDuration toRun:[
100000000 timesRepeat:[self foo:123]
].
Transcript showCR:t2-t1
EDIT: PS: J'ai oublié de mentionner: ce sont les temps depuis l'EDI (c.-à-bytecode-jitted exécution) . Le code compilé statiquement (en utilisant le compilateur stc) sera généralement un peu plus rapide (20-30%) sur ces micro-tests de bas niveau, grâce à un meilleur algorithme d'allocation de registres.
EDIT: J'ai essayé de reproduire ces chiffres l'autre jour, mais j'ai obtenu des résultats complètement différents (8ns pour l'appel simple, mais 9ns pour l'exécution). Soyez donc très prudent avec ces micro-timings, car ils fonctionnent complètement hors du cache de premier niveau (et les messages vides omettent même la configuration de contexte, ou sont insérés) - ils ne sont généralement pas très représentatifs de la performance globale.