MS: please visit also Speed of different method dispatching methods
The simplest way to call a procedure, namespaced or not, is (1) to give its full name, with arguments. For a proc exported in a namespace, you might also (2) import it so you call it by 'basename', omitting the namespace path. Also, you can (3) instruct any interpreter that a proc name like foo is an alias for another like bar, which may also have constant arguments (minor commands) appended:
interp alias {} foo {} bar grill
Finally, you can (4) indirectly wrap a proc invocation in another proc:
proc foo {x y} {bar $x $y}
Miguel Sofer has timed these four alternatives, and to our surprise found out that aliassing (3) takes double the time of (1) or (2), so even (4) is clearly better: ...on 8.4a2, at least! On my notebook I get
direct : 299050 microseconds per iteration import : 288499 microseconds per iteration interp alias : 638389 microseconds per iteration indirect : 365086 microseconds per iteration
when I run "t 10000" (a few times, until timings stabilize ...) after defining the script below.
Michael Schlenker has run the test with 8.4.1 (w2k, PII 350) and got:
direct : 361965 microseconds per iteration import : 399422 microseconds per iteration interp alias : 497514 microseconds per iteration indirect : 482034 microseconds per iteration
Seems like the penalty is getting smaller.
NEM 2008-11-13: Updated for Tcl 8.6a4 (MacOS X, dual-core 2GHz):
direct : 17720 microseconds per iteration import : 15187 microseconds per iteration interp alias : 19742 microseconds per iteration indirect : 21327 microseconds per iteration
Seems like the overhead has vanished.
namespace eval mig { proc test {} {set ::a 5} namespace export * } namespace import mig::* interp alias {} test2 {} ::mig::test proc test3 {} {::mig::test} proc t {n} { set t1 [time { for {set nn $n} {[incr nn -1]} {} { ::mig::test } }] set t2 [time { for {set nn $n} {[incr nn -1]} {} { test } }] set t3 [time { for {set nn $n} {[incr nn -1]} {} { test2 } }] set t4 [time { for {set nn $n} {[incr nn -1]} {} { test3 } }] puts "\n" puts "direct : $t1" puts "import : $t2" puts "interp alias : $t3" puts "indirect : $t4" }
RS - I would not have expected such a penalty for an interp alias. What do you others think?
DKF: The "surprising" thing is how different aliases are from namespace imports.
JBR: Or even why an import is faster than directly naming the proc??