From: aa8vb at vislab.epa.gov (Randall Hopper)
Date: Tue, 20 Apr 1999 12:37:59 GMT
Subject: Tkinter performance
In-Reply-To: <371B4B39.8B78BC7A@foreman.ac.rwth-aachen.de>; from Greg Landrum on Mon, Apr 19, 1999 at 05:26:49PM +0200
References: <371B4B39.8B78BC7A@foreman.ac.rwth-aachen.de>
Message-ID: <19990420083759.A133486@vislab.epa.gov>
Content-Length: 3994
X-UID: 1666                                                  

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




