[wxpython-users] Fast(er) pixel level access

Folkert Boonstra F.Boonstra at inter.nl.net
Sun May 4 02:34:35 PDT 2008


Christopher Barker schreef:
> Folkert Boonstra wrote:
>> Just an update on how far i got with getting it faster.
>> Replacing loops with list comprehensions is a major enhancement:
>
> I'm a bit surprised -- I thought list comprehensions gave you almost
> the same byte code. I learn something new every day.
>
> Anyway, you can easily get a 10X or so speed up for this kind  of
> thing with numpy -- it really is the tool for the job, it's well worth
> learning.
>
Yes, i'm working on that. See below.
> on further examination:
>     def applyRule(self, rule):
>         # Apply the rule
>         xdim = ydim = [d for d in range(DIM) if d>0 and d<(DIM-1)]
>
> if xdim = ydim, why make two? though they are references to the same
> thing anyway. (of course, you may be planning to generalize this to
> when x does not equal y)
>
> and: [d for d in range(DIM) if d>0 and d<(DIM-1)] is the same as:
>
> range(1,DIM-1)
>
> Let Python work for you!
>
The list comprehensions are moved out of the applyRule function now.
The applyRule was implemented 2 ways: using map(...) and just a for-loop:

def applyRule(self, rule):
    map(rule, self.xydims)

def applyRule(self, rule):
    for xy in self.xydims:
       rule(xy)

The for-loop is faster.
> Still, if you can make your rule function just take the img array, and
> process it with numpy tools, it will be much faster (less code to get
> wrong, too) -- trust me on this.
>
Ok, I picked up on an example you sent earlier.  The parity rule was:

    def parity(self, xy):
        x = xy[0]; y = xy[1]
        sum = 0
        if self.buf[x,y-1] == lifeCell:
            sum += 1
        if self.buf[x-1,y] == lifeCell:
            sum += 1
        if self.buf[x,y]   == lifeCell:
            sum += 1
        if self.buf[x+1,y] == lifeCell:
            sum += 1
        if self.buf[x,y+1] == lifeCell:
            sum += 1
        if sum == 1:
            self.buf[x,y] = lifeCell
        else:
            self.buf[x,y] = deadCell

The parity rule now using a uint8 array filled with 0 and 1:

    def parity(self, xy):
        x = xy[0]; y = xy[1]
        sum = self.bufbw[x-1:x+2, y-1:y+2].sum() \
            - self.bufbw[x-1,y-1] - self.bufbw[x+1,y-1] \
            - self.bufbw[x-1,y+1] - self.bufbw[x+1,y+1]
        if sum == 1:
            self.buf[x,y]   = lifeCell
            self.bufbw[x,y] = 1
        else:
            self.buf[x,y]   = deadCell
            self.bufbw[x,y] = 0

The self.buf is still used for the wx.BitmapFromBufferRGBA conversion to
bitmap.
The last parity function is slower that the original.
I've been looking through the numpy docs a bit to find something to let
me apply a function for each element in an array where the function can
access the surrounding elements and make a decision on the state of
those elements.
Haven't found it yet so I will ask the same thing on the numpy list.

> -Chris
>
>
Thanks again,
Folkert



More information about the wxpython-users mailing list