Version 14 of Tk Performance

Updated 2006-02-20 13:36:00

To optimize Tk performance, you should consider all the hints for Tcl Performance, as well as these issues.


Tk on Microsoft Windows can be Slow

Tk was developed under X Windows. The initial ports to Windows and Macintosh relied upon an X Window emulation. But an architectural mismatch between the two systems resulted in relatively poor performance on Windows. The situation is improving, and many in the Tcl community are considering new Tk implementations that would eliminate this problem. See http://www.multimania.com/fbonnet/Tcl/TkGS/specs.htm --RWT

JH: The above sentiment was general concensus years ago (last century), but the speed of the average PC has washed away most concerns. Tk even runs passably on PocketPC devices now.


Tk Canvas

You can speed up drawing of simple lines by explicitly declaring the line to be of zero width. --RWT

The DASH patch was incorporated into 8.3 which allows you to pass a list of coordinates to the various canvas commands rather than individual coordinate parameters. For example:

 set Coords [list 1 2 3 4 5 6 7 8]
 .c create line $Coords

is faster than the previously required

 set Coords [list 1 2 3 4 5 6 7 8]
 eval .c create line $Coords

--TFW


Batching GUI Updates

It is far faster to collect all updates you wish to make to a GUI into one place (well, one batch execute between event-servicings) than it is to do it all piece-meal, and it is best to handle updates and protocol management accordingly. You might think that this reduces the responsiveness of the GUI (and in some situations you'd be right) but since display updates are always postponed until an idle event, and since the amount of effort to actually redraw the display is usually significant, it tends to pay to try to do as much at once as you can. Which means more time can actually be spent waiting for user input. Which means the application is more responsive. DKF


Tk Event Procedures

Whenever you bind a script to an event, Tk will either execute the script directly, or, if the script contains '%' substitutions (see the bind man page) it will write a new script and evaluate it.

If you've read Tcl Performance, then you already know that eval is relatively slow, and executing byte-compiled procs is fast. So for speed (and generally good style) use procedures for events. Put the absolute minimum of code in the bind script. For example, binding a listbox mouse click to an action requires you to calculate the listbox selection index because the selection doesn't actually change until *after* the binding fires. (This is described in the Tk Usage FAQ, and is superseded by the <<ListboxSelect>> virtual event in Tcl 8.1)

  set lb [listbox .listbox1]
  pack $lb
  bind $lb <ButtonRelease-1> {select_it %W [%W nearest %y]}
  proc select_it { widget n } {
      puts "Selected [$widget get $n]"
  }

- RWT


Tk application comes up slower than it should? Run TclPro's procheck, if you haven't. It has performance warnings that will show you places to optimize your code.

If startup is a big deal, look for code that could (should) be put in a proc. Also see if you can delay loading some extensions. You can also do the same thing for building GUI forms. Don't construct the toplevel and widgets until you need them, something like:

  proc browsdata { } {
     if {[winfo exists .databrowser]} {
         wm deiconify .databrowser
     } else {
         package require SpecialWidgets
         toplevel .datababrowser
         ... 
     }

Bob Techentin on news:comp.lang.tcl

See the note on Tcl Performance regarding startup time and package loading.


DKF: It can be a big gain to cache canvas items (by moving them off-screen) instead of deleting them when you're finished since this lets you bound the number of canvas ids allocated.


Donald Arseneau: In the same vein, canvas items can be cached simply by covering them up. This is most useful when some object has several visual representations. Rather than inserting and removing images to change the appearance, one should raise the desired image. See, for example, Animations on a Canvas.

David Easton: Perhaps a better answer would be if canvas items had a visible property so that they could be hidden properly and presumably this might make some drawing routines faster as hidden items could be ignored - maybe a candidate for 8.5?

Have you tried:

 $canvas itemconfigure $item -state hidden

David Easton: I didn't know about that one - thanks.


Stefan Hartwig: I has the problem to draw very many rectangles (more than 10.000) and the performance of the program is very bad. The scrolling is very slow. Is it possible to disable the automatic tagging of canvas-items (I think this is the problem). Or is there another way to speed up the program? THX


Category Performance