Re: TclX loop slow in the default case



Alexandre Ferrieux wrote:
Evil Son wrote:
tclsh 8.5.4
17135 naive_loop <-- optimisation work kicks in as Koen/msf said.
35612 clever_loop <-- not in the 8.5.4 possible world

Argh. Donal, can you explain why, despite [uplevel] compiling its
argument, uplevelling a computed [for] doesn't approach the speed of
the naked for (nor even that of for..uplevel) ?

Yes.

Variable accesses are only efficient when they can be tied to an index
into a local variable table. This process is (probably) the #1 source of
speed in Tcl's bytecode engine (either that or the dealing with the fact
that no parsing needs to be done, but that's out of scope here). When a
script is processed with [uplevel] in 8.5 and before[*] then it cannot
be bound to local variables, resulting in each variable access for
reading or writing being done through a hash table lookup. For a [for]
loop, this is quite a significant cost!

OK, perhaps the "cannot" was a bit strong. "Has not yet been possible
to" is perhaps closer to the truth.

In the "naïve" version, the [upvar] binds the variable in the parent
scope to a local variable in the [naive_loop]'s own scope, and makes the
actual [for] loop part of it efficient (though accesses from inside the
body still suck). BTW, if you want performance out of [uplevel], always
remember to include the level argument in 8.5.

Donal.
[* This might change in 8.6. ]
.