speed up code (custom Gauge)

Hi,
since wxpython only has a 1 colored gauge (green on my W7 system) and I am trying to learn Python anyway, I am trying to build own of my own. Although the code is not ready, it looks the same and works (with yellow, red, blue, or colorchanges depending on proces) , but it is really slow (and the ligth fade over on halt is not even implemented yet).

Could someone give some advise on how to speed things up?
Please remember I am a newbie.
TIA Samuel

test021.py (13.2 KB)

Please reduce your sample to just your new gauge widget and some simple code to test it. http://wiki.wxpython.org/MakingSampleApps

···

On 3/10/10 8:55 AM, samuel samuel wrote:

Hi,
  since wxpython only has a 1 colored gauge (green on my W7 system) and
I am trying to learn Python anyway, I am trying to build own of my own.
Although the code is not ready, it looks the same and works (with
yellow, red, blue, or colorchanges depending on proces) , but it is
really slow (and the ligth fade over on halt is not even implemented yet).
Could someone give some advise on how to speed things up?
Please remember I am a newbie.

--
Robin Dunn
Software Craftsman
http://wxPython.org

Robin Dunn wrote:

Hi,
  since wxpython only has a 1 colored gauge (green on my W7 system) and
I am trying to learn Python anyway, I am trying to build own of my own.
Although the code is not ready, it looks the same and works (with
yellow, red, blue, or colorchanges depending on proces) , but it is
really slow (and the ligth fade over on halt is not even implemented yet).
Could someone give some advise on how to speed things up?
Please remember I am a newbie.

Please reduce your sample to just your new gauge widget and some simple code to test it. http://wiki.wxpython.org/MakingSampleApps

Actually, that was a pretty simple test wrapper around the class, but the class is probably bigger than it needs to be.

I haven't had time t o test anything, but a few comments that might get you started:

0) there should be no need to paths-- though I don't think those are used.

1) don't use PIL -- you don't want the dependency, and it isn't necessary. You can create a wx.Image from raw binary data, and maybe even a bitmap directly.

2) store your image as binary data in a string or maybe an array.array -- nested lists of integers is going to be pokey. numpy arrays would be even better, but it's probably better not to introduce the dependency

3) I'd calculate ht pixel values with some math, rather than hard-coding them. Simple linear gradients are pretty easy.

4) Avoid explicit IDS -- see: http://wiki.wxpython.org/wxPython%20Style%20Guide

5) you seem to have two copies of the buffer: self.PI and self._Buffer -- you only need one. In fact, you may not even need to double buffer -- if the image changes a lot, and is fast to draw, there is no reason to.

6) I'm having trouble following the code to see where you actually do the drawing, but make sure that you aren't doing a lot of image reg-generation each time. The draw should be pretty simple -- you may be able to get away with a wx.Image.Rescale to stretch the bar to the size you want.

HTH,

-Chris

···

On 3/10/10 8:55 AM, samuel samuel wrote:

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Oops, I just took a quick look at the code and couldn't see the forest for the trees. When the only class I saw that was named something like a gauge replacement (ProgressIndicator) was still using a wx.Gauge then I figured the wrong thing was sent and all the other complexity and image manipulation was just distracting.

···

On 3/11/10 12:06 PM, Chris Barker wrote:

Robin Dunn wrote:

On 3/10/10 8:55 AM, samuel samuel wrote:

Hi,
since wxpython only has a 1 colored gauge (green on my W7 system) and
I am trying to learn Python anyway, I am trying to build own of my own.
Although the code is not ready, it looks the same and works (with
yellow, red, blue, or colorchanges depending on proces) , but it is
really slow (and the ligth fade over on halt is not even implemented
yet).
Could someone give some advise on how to speed things up?
Please remember I am a newbie.

Please reduce your sample to just your new gauge widget and some
simple code to test it. http://wiki.wxpython.org/MakingSampleApps

Actually, that was a pretty simple test wrapper around the class, but
the class is probably bigger than it needs to be.

--
Robin Dunn
Software Craftsman
http://wxPython.org

Hi
@Ron: sorry I should clean up better,

@Chris: thank a lot for your hints. I am going to try some next week.
In general, the code is fast enough in its init, but too slow on
updates.
That is on my slow netbook, on my desktops is already fast.
Both the calculations of the exact number of rows as the reversed
pixels on the end of each row should go into the Init, so when
updating the gauge I only need to add leftpartrows + middlepartrows*x
* rightpartrows.
However when I did succeed in doing that yet (the gauge start looking
like it is appending in stead of growing, like I create a double
reference to colRows).

0) there should be no need to paths-- though I don't think those are used.

True: totally obsolute, forgot to delete

1) don't use PIL -- you don't want the dependency, and it isn't
necessary. You can create a wx.Image from raw binary data, and maybe
even a bitmap directly.

When possible I want to increase the speed first, then remove PIL

2) store your image as binary data in a string or maybe an array.array
-- nested lists of integers is going to be pokey. numpy arrays would be
even better, but it's probably better not to introduce the dependency

Sounds very good, will try.

3) I'd calculate ht pixel values with some math, rather than hard-coding
them. Simple linear gradients are pretty easy.

I am afraid that it is not a simple linear gradients. E.g. at the
vert. borders the colors go from light, dark to light ---> gradient
The toprows are different than the bottomrows. The corners are
different too.
I want the gauge to look like the original. It does now. The
background is 99% correct and the foreground correct till around the
17th pixel on each row. I do with less data though. But calculating
it, rather than hardcoding it was bringing down the speed, so instead
of the first 5 pixels now I hardcode all the relevant ones.

4) Avoid explicit IDS -- see:http://wiki.wxpython.org/wxPython%20Style%20Guide

Thanks.

5) you seem to have two copies of the buffer: self.PI and self._Buffer
-- you only need one. In fact, you may not even need to double buffer --
if the image changes a lot, and is fast to draw, there is no reason to.

True, thanks.

6) I'm having trouble following the code to see where you actually do
the drawing, but make sure that you aren't doing a lot of image
reg-generation each time. The draw should be pretty simple -- you may be
able to get away with a wx.Image.Rescale to stretch the bar to the size
you want.

Since I want to get as close to the original as I can, I am afraid not
so.

···

HTH,

-Chris

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Bar...@noaa.gov

samuel en wrote:

@Chris: thank a lot for your hints. I am going to try some next week.

send it again, after you've cleaned it up some.

In general, the code is fast enough in its init, but too slow on
updates.
That is on my slow netbook, on my desktops is already fast.

yeah, but you really don't want a gauge taking up noticeable processing time -- it shouldn't slow down whatever it's gaging..

1) don't use PIL -- you don't want the dependency, and it isn't
necessary. You can create a wx.Image from raw binary data, and maybe
even a bitmap directly.

When possible I want to increase the speed first, then remove PIL

the extra PIL <-> wx transition could be costing you -- though probably not much with small images, but still...

I am afraid that it is not a simple linear gradients. E.g. at the
vert. borders the colors go from light, dark to light ---> gradient
The toprows are different than the bottomrows. The corners are
different too.
I want the gauge to look like the original. It does now. The
background is 99% correct and the foreground correct till around the
17th pixel on each row. I do with less data though. But calculating
it, rather than hardcoding it was bringing down the speed, so instead
of the first 5 pixels now I hardcode all the relevant ones.

I've seen people use pre-defined bitmaps for the corners and edges, then scale them for a given size -- that may be possible here. The trick is to move the calculations and pixel-setting to native C++ code.

you may be
able to get away with a wx.Image.Rescale to stretch the bar to the size
you want.

Since I want to get as close to the original as I can, I am afraid not
so.

maybe you can make sure you are only adding a bit when the bar grows, keeping the rest the same, rather than re-building the whole thing.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov