Why does my application use too much CPU time?

All,

My application code on Windows uses less than 1% CPU time. However,
on Linux (Ubuntu 10.4), my application code uses 11% CPU time. For the
most part, my application code displays text in different colors.
Every 200ms, I need to process up to 15 characters.

Below is a sample program I put together to demonstrate the excessive
CPU usage problem.
What am I do wrong? How can I make my application code use
considerable less CPU time?

Thanks in advance,
Bruce

import wx
import threading
import time
import os

class DisplayThread (threading.Thread):
    def __init__ (self, mainw):
        threading.Thread.__init__(self)
        self.mainw = mainw
        self.runFlag = True

    def stop (self):
        self.runFlag = False

    def run (self):
  delay = 0.2 #200ms (every 200 ms, upto 15 chars need to be
displayed)
        count = 0
        while (self.runFlag == True):

            for self.ii in range (0,500):
                self.colorOutput ("A" , 'red')
                self.colorOutput ("B" , 'green')
                self.colorOutput ("C" , 'black')
                self.colorOutput ("D" , 'orange')
                self.colorOutput ("E" , 'blue')
                self.colorOutput ("F" , 'red')
                self.colorOutput ("G" , 'green')
                self.colorOutput ("H" , 'black')
                self.colorOutput ("I" , 'orange')
                self.colorOutput ("J" , 'blue')
                time.sleep (delay)
    count = count + 10
    if count >= 40:
                    self.colorOutput ("\n" , 'black')
        count = 0
            self.stop()
  os._exit (1)

    def colorOutput (self , text, color):
  selection = 0
  if selection == 0:
          wx.CallAfter (self.mainw.xdisplay,text,color) #Uses
approx 10% CPU time
  elif selection == 1:
          wx.CallAfter (self.mainw.xxdisplay,text,color) #Uses
approx 4% CPU time
  else:
    wx.CallAfter (self.mainw.xxxdisplay,text,color) #Uses approx 6%
CPU time

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition,
size=(500, 500))
        panel = wx.Panel(self, -1)
        font1 = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, False,
u'Courier New')
        style = wx.TE_READONLY | wx.TE_RICH2 | wx.TE_MULTILINE |
wx.TE_LEFT

        self.text1 = wx.TextCtrl(panel, -1, "", pos=(20,15),size =
(400,300),style = style)
        self.text1.SetFont(font1)
        self.Center()
        self.Show(True)

        self.displayThread = DisplayThread (self)
        self.displayThread.start()

    def xdisplay (self, data, color): #various colors
        start = self.text1.GetLastPosition()
        self.text1.AppendText (data)
        end = self.text1.GetLastPosition()
        style = wx.TextAttr(color, None)
        self.text1.SetStyle(start, end, style)

    def xxdisplay (self, data, color): #black only
        self.text1.AppendText (data)

    def xxxdisplay (self, data, color): #red only
        start = self.text1.GetLastPosition()
        self.text1.AppendText (data)
        end = self.text1.GetLastPosition()
        style = wx.TextAttr('red', None)
        self.text1.SetStyle(start, end, style)

application = wx.PySimpleApp()
quicktest = MyFrame(None, -1, "test 1")
application.MainLoop()

The difference could simply be differences in how the native control is implemented. The text edit widgets are really not a good match for what you are trying to do, they are designed for allowing users to type and enter text, so anything else could be a mismatch depending on the implementation. If you don't need to allow the user to edit the text then creating a simple custom widget for displaying it would probably be better.

Another thing that will help is to reduce the number of wx.CallAfters that you do. IOW, do more in each one if you can. wx.CallAfter does not impose a lot of overhead, but it's not small either.

···

On 8/5/10 9:58 AM, bruce g wrote:

All,

My application code on Windows uses less than 1% CPU time. However,
on Linux (Ubuntu 10.4), my application code uses 11% CPU time. For the
most part, my application code displays text in different colors.
Every 200ms, I need to process up to 15 characters.

Below is a sample program I put together to demonstrate the excessive
CPU usage problem.
What am I do wrong? How can I make my application code use
considerable less CPU time?

--
Robin Dunn
Software Craftsman

Hi Robin,

In my real application, I use a wx.textctrl widget (with a vertical
scrollbar) to display Unicode characters such as u25CF, u25BC ...
Every 200ms, I use wx.CallAfter to display the data. It seems to me
that displaying 15 characters every 200ms on a dual-core, 2.5gHz
processor should be insignificant.

In a simpler case, I also set the background color of a few
wx.textctrl widgets every 200ms to either white or green and this also
takes a considerable amount of CPU. I am using wx.textctrl as a
blinking indicator. Can you explain this?

If you are saying simply that under Linux, wxPython is slower than
under Windows, I can accept your answer. However, I am surprised that
more people have not complained.

Thanks again,
Bruce

···

On Aug 5, 2:54 pm, Robin Dunn <ro...@alldunn.com> wrote:

On 8/5/10 9:58 AM, bruce g wrote:

> All,

> My application code on Windows uses less than 1% CPU time. However,
> on Linux (Ubuntu 10.4), my application code uses 11% CPU time. For the
> most part, my application code displays text in different colors.
> Every 200ms, I need to process up to 15 characters.

> Below is a sample program I put together to demonstrate the excessive
> CPU usage problem.
> What am I do wrong? How can I make my application code use
> considerable less CPU time?

The difference could simply be differences in how the native control is
implemented. The text edit widgets are really not a good match for what
you are trying to do, they are designed for allowing users to type and
enter text, so anything else could be a mismatch depending on the
implementation. If you don't need to allow the user to edit the text
then creating a simple custom widget for displaying it would probably be
better.

Another thing that will help is to reduce the number of wx.CallAfters
that you do. IOW, do more in each one if you can. wx.CallAfter does
not impose a lot of overhead, but it's not small either.

--
Robin Dunn
Software Craftsmanhttp://wxPython.org

bruce g wrote:

Hi Robin,

In my real application, I use a wx.textctrl widget (with a vertical
scrollbar) to display Unicode characters such as u25CF, u25BC ...
Every 200ms, I use wx.CallAfter to display the data. It seems to me
that displaying 15 characters every 200ms on a dual-core, 2.5gHz
processor should be insignificant.

In a simpler case, I also set the background color of a few
wx.textctrl widgets every 200ms to either white or green and this also
takes a considerable amount of CPU. I am using wx.textctrl as a
blinking indicator. Can you explain this?

If you are saying simply that under Linux, wxPython is slower than
under Windows, I can accept your answer. However, I am surprised that
more people have not complained.

Thanks again,
Bruce

All,
      
My application code on Windows uses less than 1% CPU time. However,
on Linux (Ubuntu 10.4), my application code uses 11% CPU time. For the
most part, my application code displays text in different colors.
Every 200ms, I need to process up to 15 characters.
      
Below is a sample program I put together to demonstrate the excessive
CPU usage problem.
What am I do wrong? How can I make my application code use
considerable less CPU time?
      

The difference could simply be differences in how the native control is
implemented. The text edit widgets are really not a good match for what
you are trying to do, they are designed for allowing users to type and
enter text, so anything else could be a mismatch depending on the
implementation. If you don't need to allow the user to edit the text
then creating a simple custom widget for displaying it would probably be
better.

Another thing that will help is to reduce the number of wx.CallAfters
that you do. IOW, do more in each one if you can. wx.CallAfter does
not impose a lot of overhead, but it's not small either.

--
Robin Dunn
Software Craftsmanhttp://wxPython.org
    

Try benchmarking your application with/without the CallAfters
(especially if you can reduce your whole application to as small
codebase as possible, removing extra "fluff"). You could also try
benchmarking Windows vs Linux, may be interesting

···

On Aug 5, 2:54 pm, Robin Dunn <ro...@alldunn.com> wrote:

On 8/5/10 9:58 AM, bruce g wrote:

--
Steven Sproat, BSc

Hi Steve,

For the most part, I have done what you suggested.
Under Windows, my application and sample code use less than 1 percent of the CPU.
Under Linux, my application and sample code use approx 10% of the CPU.
If you look at the function colorOutput, you will see I tried various types of outputs (various color, black only, red only) and the CPU usage various. My results are listed to the right of the function calls.
As for the wx.CallAfter, I need this otherwise my program will crash; needed because another thread is writing to the main screen window.

Bruce

···

On Thu, Aug 5, 2010 at 3:52 PM, Steven Sproat sproaty@gmail.com wrote:

bruce g wrote:

Hi Robin,

In my real application, I use a wx.textctrl widget (with a vertical

scrollbar) to display Unicode characters such as u25CF, u25BC …

Every 200ms, I use wx.CallAfter to display the data. It seems to me

that displaying 15 characters every 200ms on a dual-core, 2.5gHz

processor should be insignificant.

In a simpler case, I also set the background color of a few

wx.textctrl widgets every 200ms to either white or green and this also

takes a considerable amount of CPU. I am using wx.textctrl as a

blinking indicator. Can you explain this?

If you are saying simply that under Linux, wxPython is slower than

under Windows, I can accept your answer. However, I am surprised that

more people have not complained.

Thanks again,

Bruce

On Aug 5, 2:54 pm, Robin Dunn ro...@alldunn.com wrote:

On 8/5/10 9:58 AM, bruce g wrote:

All,

My application code on Windows uses less than 1% CPU time. However,

on Linux (Ubuntu 10.4), my application code uses 11% CPU time. For the

most part, my application code displays text in different colors.

Every 200ms, I need to process up to 15 characters.

Below is a sample program I put together to demonstrate the excessive

CPU usage problem.

What am I do wrong? How can I make my application code use

considerable less CPU time?

The difference could simply be differences in how the native control is

implemented. The text edit widgets are really not a good match for what

you are trying to do, they are designed for allowing users to type and

enter text, so anything else could be a mismatch depending on the

implementation. If you don’t need to allow the user to edit the text

then creating a simple custom widget for displaying it would probably be

better.

Another thing that will help is to reduce the number of wx.CallAfters

that you do. IOW, do more in each one if you can. wx.CallAfter does

not impose a lot of overhead, but it’s not small either.

Robin Dunn

Software Craftsmanhttp://wxPython.org

Try benchmarking your application with/without the CallAfters

(especially if you can reduce your whole application to as small

codebase as possible, removing extra “fluff”). You could also try

benchmarking Windows vs Linux, may be interesting

Steven Sproat, BSc

http://whyteboard.org/

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

Hi Robin,

In my real application, I use a wx.textctrl widget (with a vertical
scrollbar) to display Unicode characters such as u25CF, u25BC ...
Every 200ms, I use wx.CallAfter to display the data. It seems to me
that displaying 15 characters every 200ms on a dual-core, 2.5gHz
processor should be insignificant.

wx.CallAfter works by sending a wx.Event containing info about the callable object to be called and the parameters to be passed to it. Before that event can be processed any currently pending events will need to be processed first because events coming from other threads are processed just before the idle events are sent. Then each pending call-after (or other) event is processed and in the case of the call-afters the callable object is called. So you can see that there is a small but non-trivial amount of overhead for each of them, especially if while processing a call-after something is done that causes more events to be sent (like updating a textctrl) which in turn will cause any pending call-afters to have to wait again while the other events are processed. So assuming you know all 15 characters/colors at the same time, using one call-after for all of them together will be better than one for each of them.

In a simpler case, I also set the background color of a few
wx.textctrl widgets every 200ms to either white or green and this also
takes a considerable amount of CPU. I am using wx.textctrl as a
blinking indicator. Can you explain this?

If you are saying simply that under Linux, wxPython is slower than
under Windows, I can accept your answer. However, I am surprised that
more people have not complained.

What I'm saying is that it may be possible that the GTK text widget is not as efficient for lots of little text appends and attribute settings than it is for more normal text widget use cases, and if that's the case then making a custom text display widget that meets your needs might be faster and better.

···

On 8/5/10 12:27 PM, bruce g wrote:

--
Robin Dunn
Software Craftsman

Hi Robin,

Color Text Issue:

I agree with your statement to use
one call-after to display a group of common character colors. In my real
application, I use a call-after every 200ms to process up to 15 characters.
However, I do not append to the wx.TextCtrl until a character color change
occurs. This approach helped tremendously reducing CPU usage. My posted example
was not representative of my real application code.

Blinking Indicator Issue:

wx.TextCtrl seems to be a natural to
implement a blinking indicator. Simply set the background color to white or
green accordingly. Under Windows, this processing took effectively 0% CPU time. However,
under Linux, this was taking almost 4% CPU time. My work around was to overlay
another widget on top and use show/hide to implement a blinking indicator (CPU
usage dropped to 1%).

In both of the above issues, I use wx.TextCtrl
and I am very pleased to the visual results, just not the CPU usage. What do
you mean by making a custom text display widget?

Thanks again for your help,

Bruce

···

On Fri, Aug 6, 2010 at 2:46 PM, Robin Dunn robin@alldunn.com wrote:

On 8/5/10 12:27 PM, bruce g wrote:

Hi Robin,

In my real application, I use a wx.textctrl widget (with a vertical

scrollbar) to display Unicode characters such as u25CF, u25BC …

Every 200ms, I use wx.CallAfter to display the data. It seems to me

that displaying 15 characters every 200ms on a dual-core, 2.5gHz

processor should be insignificant.

wx.CallAfter works by sending a wx.Event containing info about the callable object to be called and the parameters to be passed to it. Before that event can be processed any currently pending events will need to be processed first because events coming from other threads are processed just before the idle events are sent. Then each pending call-after (or other) event is processed and in the case of the call-afters the callable object is called. So you can see that there is a small but non-trivial amount of overhead for each of them, especially if while processing a call-after something is done that causes more events to be sent (like updating a textctrl) which in turn will cause any pending call-afters to have to wait again while the other events are processed. So assuming you know all 15 characters/colors at the same time, using one call-after for all of them together will be better than one for each of them.

In a simpler case, I also set the background color of a few

wx.textctrl widgets every 200ms to either white or green and this also

takes a considerable amount of CPU. I am using wx.textctrl as a

blinking indicator. Can you explain this?

If you are saying simply that under Linux, wxPython is slower than

under Windows, I can accept your answer. However, I am surprised that

more people have not complained.

What I’m saying is that it may be possible that the GTK text widget is not as efficient for lots of little text appends and attribute settings than it is for more normal text widget use cases, and if that’s the case then making a custom text display widget that meets your needs might be faster and better.

Robin Dunn

Software Craftsman

http://wxPython.org

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

Creating a class where you bind EVT_PAINT and draw the text (or whatever you want to display) in your paint event handler.

···

On 8/6/10 1:08 PM, bruce g wrote:

What do you mean by making a
custom text display widget?

--
Robin Dunn
Software Craftsman