A newbie learns... [Part 1]

Gregory A. Landrum landrum at foreman.ac.rwth-aachen.de
Wed Jun 2 02:46:27 EDT 1999


Howdy,

I'm in the process of learning python, Tkinter and all that good
stuff. I'm doing this by writing an application which, hopefully, will
actually be useful.  Along the way, I'm experimenting and playing and
trying to figure out how to make things go faster/better.

What I figure is that as I find tricks which I think might be useful
to other people trying to learn python, I'll post them.  Mabye other
newbies will also find them useful.  

If people find this a waste of time/space/electrons, let me know and I
won't continue.

---------

I (Tkinter) Drawing lines/polygons made up of many points.

The easy way to do this is to create a 1D array of x,y pairs (i.e
something like this: [x1, y1, x2, y2, ... xn, yn]) and then call
Canvas.create_lines:

  canvas.create_line(data,width=width,fill=color,tags="foo");

unforunately, that's also pretty slow.  Tkinter takes your nice array
of x,y pairs and, using Tkinter._flatten, turns it into the tuple
which actually gets passed to Tk.  This is wonderfully general, but
pretty slow.  Luckily, since we know the structure of the data, we can
bypass this by forming the tuple ourselves and making the Tk call
directly: 

  tpl = tuple(data);
  apply(canvas.tk.call,
        (canvas._w,'create','line') + tpl +
        ('-width',width,'-fill',color,'-tags',"foo"));
  
This results in a huge speed up when the line contains a lot of
points.  For example, on my machine when the number of points in the
line is 4000, it takes ~10 seconds to flatten the list of points prior
to drawing (first method).  The second method takes less than half a
second.  The relative difference increases dramatically with
increasing numbers of points.

The same exact trick can be used with polygons:

  tpl = tuple(data);
  apply(canvas.tk.call,
        (canvas._w,'create','polygon') + tpl +
        ('-width',width,'-fill',color,'-tags',"foo"));

is way faster than:

  canvas.create_polygon(data,width=width,fill=color,tags="foo");

---------

II Building lists

This isn't related to Tk at all, but it is something that makes a huge
difference in speed.  I naively assumed that a good way to grow a list
was to just do something like:

    fooarray = fooarray + [data];

This is, once again, completely wrong.  This is the *slow* way of
doing things.  It's much better to do:

    fooarray.append(data);

For example, this function:

def test1(num):
  fooarr = [];
  for i in xrange(num):
    fooarr = fooarr + [i];

takes almost 14 seconds on my machine when num=10000, whereas this
one:

def test2(num):
  fooarr = [];
  for i in xrange(num):
    fooarr.append(i);

takes less than a tenth of a second.  Now *that* is a speedup.

---------

-greg

---------------------
Dr. Greg Landrum  (landrumSPAM at foreman.ac.rwth-aachen.de)
Institute of Inorganic Chemistry
Aachen University of Technology





More information about the Python-list mailing list