Tcl 8.0 performance advice

The following discussion addresses performance issues that were corrected in Tcl 8.4, but held in the 8.0--8.3 time range. It has been removed from the page on Tcl Performance in the interest of not confusing readers of that page.


  • Don't use return to get a value out of a simple procedure. set at the end of the proc (or anything else that produces a value in the right way) will be significantly faster due to the lack of error-checking overheads.

Wait a minute! What EXACTLY do you mean here?? Lets see what I get:

 proc foo {} { return foo }
 % time { foo } 1000
 31 microseconds per iteration

 proc foo {} { uplevel set bar foo }
 % set bar {}
 % time { foo } 1000
 72 microseconds per iteration

 proc foo {} { set ::bar foo }
 % time { foo } 1000
 15 microseconds per iteration

Hmmm... Tcl7.5 could do a return in 5 us. What happened? -PSE

On OSX "Tiger" (iBook G4) using 8.4.13 I get the following:

 proc foo {} { return foo }
 % time { foo } 1000
 3.806 microseconds per iteration

 proc foo {} { uplevel set bar foo }
 % set bar {}
 % time { foo } 1000
 18.565 microseconds per iteration

 proc foo {} { set ::bar foo }
 % time { foo } 1000
 5.107 microseconds per iteration

The machinery to implement return is not all that simple, and has a fair old cost associated with it. However, in your code above you should be aware that the first example has completely different semantics to the other two (returns a value, as opposed to setting a variable in the surrounding/global context.) Compare your first example with:

  proc foo {} { set foo foo }

However, my workstation is sufficiently fast that measuring the difference between these is impossible (the margin of error is just too high!) - DKF

Ack. Yes. Same here. I see today that it is impossible to do meaningful benchmarks unless they are run as a script that runs the compared code in as rapid succession as possible, too much network related interference to make any sense of the results otherwise. Guess I need to do all my benchmarking on my Linux box at home and just figure that the sun boxes will give similar relative performance -PSE

I have my doubts about this optimisation. What I get (NT4.0, TclPro1.2) is:

 % proc foo1 {} {return foo}
 % proc foo2 {} {set foo foo}
 % time {foo1} 1000000
 4 microseconds per iteration
 % time {foo2} 1000000
 3 microseconds per iteration

Maybe this optimisation is obsolete, or its actual effect is too light to be under consideration? - jp

DKF: You should be aware of the fact that UNIX has a much smaller time granularity than Windows (certainly 95/98 and quite probably NT too.) The best way to benchmark a tiny snippet of Tcl (especially where it is platform-independent code you're testing) is to use a slow UNIX box. The slowness of its operation allows for sensitivity and the fine granularity of its timer lets you pick up what differences there are. And then you have to pray that the relative speeds scale as you move to different platforms/architectures and/or faster machines. Which is usually a good assumption if you're not shimmering between numbers and strings (where performance seems to vary a lot according to the vendor's implementation of the C library.)