Re: [wxPython] DrawLines and a bunch points
by eric other posts by this author
May 1 2002 4:45PM messages near this date
[wxPython] DrawLines and a bunch points
|
Re: [wxPython] DrawLines and a bunch points
Hey Bryan,
Thanks. It is interesting to see that it is faster on on your machine with the
wxPython overhead than it is, even with my hack, on a faster windows machine 850
MHz.
Anyway, I think there is something strange on my machine. I'll look into it
further.
thanks for the benchmarks.
eric
----- Original Message -----
From: "bryan cole" <bryan.cole@[...].uk>
To: <wxpython-users@[...].org>
Sent: Wednesday, May 01, 2002 4:21 AM
Subject: Re: [wxPython] DrawLines and a bunch points
> Just tried your test-script on my linux box: I always get a value of
> between 0.1 and 0.15 (wxGTK/wxPython 2.3.2-1, RHlinux7.1, 500MHz PIII,
> no graphics card)
>
> Bryan
>
> On Mon, 2002-04-29 at 23:37, eric wrote:
> > Hello,
> >
> > I've run into an issue when drawing a line with a large number of points
using
> > DrawLines. I've attached code below that simply draws a Numeric array of
30000
> > points into a window. When the window is resized, it regenerates the point
list
> > and draws the points again. When the 30000 points are initially drawn to
the
> > window, they are very fast (.07 seconds), but subsequent draws after a
resize
> > are much slower (sometimes 2 orders of magnitude. Here is the output from
my
> > little test script when using DrawLines. The first timing is when the
window
> > initially appears. The others are after a resize. This is using
wxPython2.3.2
> > with Python 2.1.3 on windows 2000.
> >
> > C:\home\ej\wrk\chaco>python faster.py
> > 30001
> > wxPython DrawLines: 0.0752268793939
> > 30000
> > wxPython DrawLines: 0.327031508194
> > 30000
> > wxPython DrawLines: 6.30562264198
> > 30000
> > wxPython DrawLines: 6.32888677192
> > 30000
> > wxPython DrawLines: 4.22979680378
> >
> > I thought maybe the wxPython overhead was the problem, so I used
weave.inline to
> > bypass the wxPython stuff and draw the win32 PolyLine API routine directly.
I
> > got the same lousy result.
> >
> > C:\home\ej\wrk\chaco>python faster.py
> > 30001
> > str: _1878900_wxPaintDC_p <weave debug output>
> > Call to Polyline: 1.30914739164 <slower due to loading a dll>
> > 30001
> > str: _1878900_wxPaintDC_p
> > Call to Polyline: 0.285114728269
> > 30000
> > str: _1878900_wxPaintDC_p
> > Chunked calls to Polyline: 5.18981490664
> > 30000
> > str: _1878900_wxPaintDC_p
> > Call to Polyline: 0.327584651122
> > 30001
> > str: _1878900_wxPaintDC_p
> > Call to Polyline: 6.85253796223
> > 30000
> > str: _1878900_wxPaintDC_p
> > Call to Polyline: 4.44026182099
> >
> > Further poking around showed that the slow down was much worse than linear
with
> > the number of points being drawn. This seemed wierd, but I went ahead and
set
> > things up to draw the line in small chunks of 100 points to see if that
helped.
> > It did in a major way.
> >
> > C:\home\ej\wrk\chaco>python faster.py
> > 30001
> > str: _1878900_wxPaintDC_p
> > Chunked calls to Polyline: 1.49216897678 <slow because it is loading a DLL>
> > 30000
> > str: _1878900_wxPaintDC_p
> > Chunked calls to Polyline: 0.199176990372
> > 30000
> > str: _1878900_wxPaintDC_p
> > Chunked calls to Polyline: 0.318512827748
> > 30000
> > str: _1878900_wxPaintDC_p
> > Chunked calls to Polyline: 0.316748078317
> > 30000
> > str: _1878900_wxPaintDC_p
> > Chunked calls to Polyline: 0.266672160847
> >
> > All this background to ask some non-wxPython questions (though related...):
> >
> > 1. Can anyone verify that they get the same behavior with
> > DrawLines? <I wondering if something is strange about
> > my machine setup>
> > Verifying the weave behavior requires a CVS version of
> > weave -- I'm less interested in this, and it'll require
> > effort.
> >
> > 2. Does anyone have any insight into what is going on here?
> >
> > a. Why is PolyLine fast for the initial call and slow for
> > subsequent calls with a large number of points?
> >
> > b. Why is PolyLine slow for a large number of points?
> > Heck, 30000 isn't even all that large of a number.
> >
> > 3. Does Linux have the same problem?
> >
> > 4. Am I missing an extra call somewhere that would fix all my
> > problems?
> >
> > The code below is the demo. It does require Numeric, but doesn't require
> > weave unless you restore the commented out code in the OnPaint routine.
> > As a side benefit, it does show a nice example of how to use weave with
> > wxPython.
> >
> > thanks for any hints,
> >
> > eric
> >
> > --
> > Eric Jones <eric at enthought.com>
> > Enthought, Inc. [www.enthought.com and www.scipy.org]
> > (512) 536-1057
> >
> > """ Implements a fast replacement for calling DrawLines with an array as an
> > argument. It uses weave, so you'll need that installed.
> >
> > I wrote this because I was seeing very bad performance for DrawLines
when
> > called with a large number of points -- 5000-30000. Now, I have found
the
> > performance is sometimes OK, and sometimes very poor. Drawing to a
> > MemoryDC seems to be worse than drawing to the screen. My first cut of
the
> > routine just called PolyLine directly, but I got lousy performance for
this
> > also. After noticing the slowdown as the array length grew was much
worse
> > than linear, I tried the following "chunking" algorithm. It is much
more
> > efficient (sometimes by 2 orders of magnitude, but usually only a factor
> > of 3). There is a slight drawback in that it will draw end caps for
each
> > chunk of the array which is not strictly correct. I don't imagine this
is
> > a major issue, but remains an open issue.
> >
> > """
> >
> > from Numeric import *
> >
> > polyline_code = > > """
> > // uses a grouping approach because drawing seems to be veeery slow for
> > // a large number of lines.
> > // Hmmm. Further inspection shows that this isn't always the case, but
> > // don't have the time to track down the causes. It seems to always be
> > // fast using this algorithm.
> >
> > int *p_data = line_data;
> > HDC hdc = (HDC) dc->GetHDC();
> >
> > const int n_pts = _Nline[0];
> > const int bunch_size = 100;
> > const int bunches = n_pts / bunch_size;
> > const int left_over = n_pts % bunch_size;
> >
> > for (int i = 0; i < bunches; i++)
> > {
> > Polyline(hdc,(POINT*)p_data,bunch_size);
> > p_data += bunch_size*2; //*2 for two longs per point
> > }
> > Polyline(hdc,(POINT*)p_data,left_over);
> > """
> >
> > def polyline(dc,line):
> > """
> > """
> > import weave
> >
> > shp = line.shape
> > assert(len(shp)==2 and shp[1] == 2)
> > if (line.typecode() != Int32 or
> > not line.iscontiguous()):
> > line = line.astype(Int32)
> > weave.inline(polyline_code,['dc','line'])
> >
> > if __name__ == '__main__':
> > from wxPython.wx import *
> > import time
> >
> > class Canvas(wxWindow):
> > def __init__(self, parent, id = -1, size = wxDefaultSize):
> > wxWindow.__init__(self, parent, id, wxPoint(0, 0), size,
> > wxSUNKEN_BORDER | wxWANTS_CHARS)
> >
> > self.point_count = 30000
> > self.calc_points()
> > EVT_PAINT(self, self.OnPaint)
> > EVT_SIZE(self, self.OnSize)
> >
> > def calc_points(self):
> > w,h = self.GetSizeTuple()
> > from RandomArray import *
> > x = arange(0., w, float(w)/self.point_count)
> > y = randint(0., h, len(x))
> > self.points = concatenate((x[:,NewAxis],y[:,NewAxis]),-1)
> >
> > def OnSize(self,event):
> > self.calc_points()
> > self.Refresh()
> >
> > def OnPaint(self,event):
> > print len(self.points)
> > dc = wxPaintDC(self)
> > dc.SetPen(wxRED_PEN)
> > dc.BeginDrawing()
> >
> > t1 = time.clock()
> > dc.DrawLines(self.points)
> > t2 = time.clock()
> > print 'wxPython DrawLines:', t2-t1
> >
> > """
> > # This first call is slow because your either compiling (very
slow)
> > # or loading a DLL (kinda slow)
> > # Resize the window to get a more realistic timing.
> > t1 = time.clock()
> > dc.SetPen(wxGREEN_PEN)
> > polyline(dc,self.points)
> > t2 = time.clock()
> > print 'Chunked calls to Polyline:', t2-t1
> > """
> > dc.EndDrawing()
> >
> > class CanvasWindow(wxFrame):
> > def __init__(self, id=-1, title='Canvas',size=(500,500)):
> > parent = NULL
> > wxFrame.__init__(self, parent,id,title, size=size)
> > self.canvas = Canvas(self)
> > self.Show(1)
> >
> > class MyApp(wxApp):
> > def OnInit(self):
> > frame = CanvasWindow(title="Speed Examples",size=(500,500))
> > frame.Show(true)
> > return true
> >
> > app = MyApp(0)
> > app.MainLoop()
> >
> >
> >
> >
> >
> > _______________________________________________
> > wxpython-users mailing list
> > wxpython-users@[...].org
> > http://lists.wxwindows.org/mailman/listinfo/wxpython-users
> --
> Bryan Cole
> Teraview Ltd., 302-304 Cambridge Science Park, Milton Road, Cambridge
> CB4 0WG, United Kingdom.
> tel: +44 (1223) 435380 / 435386 (direct-dial) fax: +44 (1223) 435382
>
>
> _______________________________________________
> wxpython-users mailing list
> wxpython-users@[...].org
> http://lists.wxwindows.org/mailman/listinfo/wxpython-users
_______________________________________________
wxpython-users mailing list
wxpython-users@[...].org
http://lists.wxwindows.org/mailman/listinfo/wxpython-users
Thread:
eric
eric
Robin Dunn
bryan cole
bryan cole
eric
Robin Dunn
bryan cole
|