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 Window. 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 [TJE] -- One thing that bothers me is all the memory copying going on, especially for huge coordinate sets. The 'line' object takes a list of coordinates as input and copies them to an internal array of doubles. If I'm generating coordinates externally, I must 1) obtain the data, 2) copy it into a Tcl list, and 3) create/update a line object with that list, leaving a trail of malloc/free waste behind me. What if the line object could recognize and accept a Tcl binary object holding the array of doubles? Well, it works nicely so far! I copied the line object's source file and created my own line type using a single binary object as input. The Tcl_Obj pointer input is type-verified, length-verified (must be even), tagged with Tcl_IncrRef, and stored as the coordinate set. Now I can create 'bline' objects out of huge chunks of binary data I receive from an external source. ---- '''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 <> [virtual event] in Tcl 8.1) set lb [listbox .listbox1] pack $lb bind $lb {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 have 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 ''You might want to post to comp.lang.tcl about your problems -- something in your algorithm is probably slowing you down. On my box I'm able to create 10,000 rectangles of random size and color in about 200ms, and that includes the overhead of calling expr about 65,000 times. Scrolling is a tiny bit jerkey though, but still what I would call acceptable.'' Is it possible to combine the fast drawing of ''canvas create rectangle'' with the speed of scrolling over a canvas image? Whats the difference between drawing rectangles in a canvas and in an image, that makes the drawing in am image such slow? ---- [Category Performance]