Mailing List Archive

Tkinter performance
While I'm at it, I have a performance question about Tkinter.

I am thinking about doing a python/Tkinter port of a program
which currently uses C/Xlib (or C/quickdraw on the Mac). I'd
love to get this to work because then I would (finally) have
a version which could work under Win95/98/NT. But I'm worried
about performance issues.

The program does 3D graphics (molecular/crystal visualization
and orbital plots). I handle all of the perspective/transformation
stuff myself, so I don't need any 3D functionality. I do need
something which can draw reasonably quickly however.

Suppose I need to draw a couple hundred circles and several
thousand line segments (these are mostly connected, so I can
use things like XDrawLines to cut down function calls) at
every update.
1) Can Tkinter on a "typical" PC (say a P200) deliver a
"reasonable" update rate (a couple of frames per second
would probably cut it)?
2) Is there anyway to do double-buffering to avoid flashing
during redraws?

I am guessing that the answer to both of these of these questions
is "No", but I'd love to hear a contrary opinion.

I have considered using something like wxPython, but that cuts
the portability of the application down rather than increasing
it. At least until there are bindings for the Motif/Lesstif
versions of wxWindows.

thanks for any help,
-greg

--
---------------------
Dr. Greg Landrum (landrum.NOSPAM@foreman.ac.rwth-aachen.de)
Institute of Inorganic Chemistry
Aachen University of Technology
Tkinter performance [ In reply to ]
On Mon, 19 Apr 1999, Greg Landrum wrote:

> While I'm at it, I have a performance question about Tkinter.
>
> I am thinking about doing a python/Tkinter port of a program
> which currently uses C/Xlib (or C/quickdraw on the Mac). I'd
> love to get this to work because then I would (finally) have
> a version which could work under Win95/98/NT. But I'm worried
> about performance issues.
>
> The program does 3D graphics (molecular/crystal visualization
> and orbital plots). I handle all of the perspective/transformation
> stuff myself, so I don't need any 3D functionality. I do need
> something which can draw reasonably quickly however.
>
> Suppose I need to draw a couple hundred circles and several
> thousand line segments (these are mostly connected, so I can
> use things like XDrawLines to cut down function calls) at
> every update.
> 1) Can Tkinter on a "typical" PC (say a P200) deliver a
> "reasonable" update rate (a couple of frames per second
> would probably cut it)?
> 2) Is there anyway to do double-buffering to avoid flashing
> during redraws?
>
> I am guessing that the answer to both of these of these questions
> is "No", but I'd love to hear a contrary opinion.

I'd suggest using PyOpenGL with the NumPy extension. In combination, it
can be quite fast, by pushing the loops to C extension modules. The only
portability problem is to the mac -- there is no Togl widget for the mac
yet.

http://starship.python.net/~da/PyOpenGL

--david ascher
Tkinter performance [ In reply to ]
>
> I'd suggest using PyOpenGL with the NumPy extension. In combination, it
> can be quite fast, by pushing the loops to C extension modules. The only
> portability problem is to the mac -- there is no Togl widget for the mac
> yet.

Another alternative would be the excellent Visualization Toolkit
Library, freely available from http://www.kitware.com. It is a large
cross-platform C++ class library for building 2D and 3D data
visualization apps which has both Python and tcl/tk bindings.


--
Bryan Van de Ven
Applied Research Labs
University of Texas, Austin
Tkinter performance [ In reply to ]
Greg Landrum:
|I am thinking about doing a python/Tkinter port of a program
...
|The program does 3D graphics (molecular/crystal visualization
|and orbital plots). I handle all of the perspective/transformation
|stuff myself, so I don't need any 3D functionality. I do need
|something which can draw reasonably quickly however.
|
|Suppose I need to draw a couple hundred circles and several
|thousand line segments (these are mostly connected, so I can
|use things like XDrawLines to cut down function calls) at
|every update.
|
|1) Can Tkinter on a "typical" PC (say a P200) deliver a
|"reasonable" update rate (a couple of frames per second
|would probably cut it)?

A few folks already mentioned PyOpenGL and VTK. The plus for OpenGL is of
course the use of its display lists which makes redraws much faster.
Hopefully TkGS will take off in the Tk world and OpenGL-accelerate the
canvas by default when OpenGL is available.

VTK is a good option, but just to give you a flavor of raw canvas
performance, I can give you some samplings from my experiments.

The canvas seems to have good internal optimizations. Given variability of
usage (not to mention different platforms which is also an issue), this is
just to give you a ballpark idea for performance on UNIX.

Using Tk8.0 under Tkinter, here are some times for loading and drawing map
lines using Tkinter (under SGI IRIX):

Load Times (approx):

#lines (#vertices) Onyx Indigo2
600 ( 1,200) 0:02 0:18
2,000 ( 15,000) 0:05 0:30
30,000 (180,000) 0:52 6:00

Draw Rates (worst case - approx):

#lines (#vertices) Onyx Indigo2
600 ( 1,200) 6-7 fps 6-7 fps
2,000 ( 15,000) 5-6 fps 5-6 fps
30,000 (180,000) 1 fps 0.4 fps

Onyx - 195MHz R10000
Indigo2 - 100Mhz R4000

I should mention that the Indigo2 is local. The Onyx X redraws are
traversing a 10base ethernet to get here, so frame rates take a hit there.

Note that the canvas seems to have respectable optimizations in place so
the less that is visible (e.g. the more you're zoomed in, the faster
redraws get. Also if only a partial area needs redrawn, it redraws it
fairly quickly relative to the full-expose frame rate. It's obvious
there's some optimization going on when you load to make drawing faster. I
wish there were a "bulk-load" feature so this loading would be faster.

Also, operations which can occur in C code are quick. E.g. telling the
canvas to scale and translate all 180,000 vertices (used for zooming the
canvas) occurs in around 1-2 seconds even on the slower Indigo2.

|2) Is there anyway to do double-buffering to avoid flashing
|during redraws?

It may be completely different on your OS, but here on SGI IRIX, redraws
appear all at once. It may be drawing into an off-screen pixmap/image, and
blitting to the screen. At any rate, no flashing occurs. YMMV.

You might just try loading up some of your data. It really takes very few
lines of code to load up the canvas and play with performance. Be sure to
set width=0 for your lines. This appears to enable some internal
optimizations for drawing lines:

canvas.create_line( vertices, width=0, fill="white" )

If the performance you see appears marginal, you might look into using VTK.
It's got good coverage of visualization primitives and operations. It will
use OpenGL when present (so you get use of your hardware display lists for
fast redrawing). It also supports (unlike the canvas) level-of-detail
rendering. So if the refresh rate isn't up to a certain threshold, it will
render objects using a simpler representation (bounding box, etc). to keep
interactivity up during pans, zooms, etc. and then render in full detail
when the "render-barrage" quits. I've worked with these same datasets in
VTK, registering them as PolyData with LODActors and gotten much better
interactive performance.

Randall
Tkinter performance [ In reply to ]
Randall Hopper <aa8vb@vislab.epa.gov> wrote:
> Note that the canvas seems to have respectable optimizations in place so
> the less that is visible (e.g. the more you're zoomed in, the faster
> redraws get. Also if only a partial area needs redrawn, it redraws it
> fairly quickly relative to the full-expose frame rate. It's obvious
> there's some optimization going on when you load to make drawing faster.

some background: the canvas widget uses a straight-forward
"damage/repair" model. changes to the canvas, and external
events such as Expose, all update a single "dirty rectangle".
they also register an idle task (after_idle) which redraws the
canvas when you get back to the main loop.

when it's time to redraw the canvas, the widget starts by
allocating a pixmap (on X windows, this is an image memory
stored on the display) with the same size as the dirty rectangle.
it then loops over the canvas items, and redraws *all* items
whose bounding box touch the dirty rectangle (this means
that diagonal lines may be redrawn also if they don't actually
cover the rectangle, but this is usually no big deal). finally,
the widget copies the pixmap to the display (this last step is
a very fast operation on all modern hardware), and releases
the pixmap.

a few additional notes:

-- most Tk widgets use double-buffering to prevent flicker
(this includes simple widgets like buttons and labels). there's
no way to change this in current version of Tk.

-- most Tk widgets also use delayed drawing. that is, they
respond to modifications and external events by scheduling
an idle task, not by updating the screen directly. there's
no way to change this in current versions of Tk.

-- the repeated allocation of pixmaps can seriously affect
performance if you're animating stuff in a maximized window
on a large truecolor display... (we all have 1800x1440 24-bit
displays, don't we?)

-- since the canvas uses a *single* dirty rectangle, you can
get better performance in some situations by forcing updates.
for example, if you're changing things in different parts of the
canvas without returning to the main loop, adding explicit
calls to update_idletasks() allows the canvas to update a
few small rectangles, instead of a large one with many more
objects.

-- the text widget is a bit smarter than the canvas...

-- guess I should mention uiToolkit here, but I'll leave that
for another day...

</F>
Tkinter performance [ In reply to ]
Randall Hopper:
|Greg Landrum:
| |Suppose I need to draw a couple hundred circles and several
| |thousand line segments (these are mostly connected, so I can
...
| |1) Can Tkinter on a "typical" PC (say a P200) deliver a
| |"reasonable" update rate (a couple of frames per second
| |would probably cut it)?
...
|The plus for OpenGL is of course the use of its display lists which makes
|redraws much faster. Hopefully TkGS will take off in the Tk world and
|OpenGL-accelerate the canvas by default when OpenGL is available.

A correction. I assumed TkGS's plan to use OpenGL when available implied
it would use OpenGL display lists. That's not the case. I just swapped
mail with Frederic BONNET of TkGS and he said current plans don't call for
using OpenGL display lists in TkGS.

(I asked him to reconsider this design choice.)

Randall