ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> wxPython-users
wxPython-users
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

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved