Donal K. Fellows's Faster Command Evaluation Stuff


A Faster [eval] Command - C

For users of Tcl 8.0, 8.1 and 8.2, this code provides a route for executing commands that improves over the performance of the eval command by a substantial margin.

Tcl8 is much faster than Tcl7 for most things, but when you start to sling about large lists, something where it should excel, it starts to have trouble with the strain (I've got code where Tcl8 is actually slower than Tcl7 due to this problem), which is where this code comes in. One of the most common constructs I use in Tcl, especially when writing extensions, is [eval [list $command $arg1 $arg2 ...] $args] to perform an evaluation taking a variable number of arguments without substitution (and it is a case which I think it should be possible to optimise quite nicely within the compiler) and this code forms a drop-in replacement for that.

When compiled, this produces the command object:fasteval command ?arg ...? arglist (it is part of an object system that I'm working on) which appends arglist to the list of arguments, and the executes the command without using Tcl's eval. Note that there is no second round of evaluation - the arguments that object:fasteval sees are the arguments that the command sees. Indeed, since the internal representations are passed to the command, this has a particularly good effect on performance over eval, since strings are only used where actually necessary.

Bugs:

A Faster [eval] Command - Pure Tcl

For users of Tcl 8.0, 8.1 and 8.2, this code provides a route for executing commands that improves over the performance of the eval command by a substantial margin.

This script that implements the command ::fasteval::fasteval that is almost exactly like the standard Tcl eval except faster.

Note that the system does not handle comments or multiple commands correctly at all, and putting that support in would make the speedup trick used impossible.

A Faster Eval - Tcl 8.3 and later

The above techniques are no longer needed. From the C level, you can call Tcl_EvalObjv() and from the Tcl level you can simply make sure that the arguments you pass to eval are pure lists (i.e. lists which have no string interpretation.) Using these techniques have additional advantages over particularly the C code above, in that autoloading and command modification work, and all commands are supported. You can force a list to be pure by using the lrange command, like this:

set pureList [lrange $dirtyList 0 end]

You should note that many lists are naturally pure anyway, but list-like literals are invariably not.

As a bonus, the concat command works much faster on pure lists too.

Back to the main index.


Donal. K. Fellows, Computer Science, University of Manchester, U.K. / Tcl Core Team