Configtool: speed up startup with wx-tricks.

This should fix issue #235.

Recently ConfigTool has been very slow for me on Ubuntu Linux.
When I run the app there is a 15 second wait before the window is
first displayed.  I bisected the problem and found it was tied to
the number of pins in `pinNames`, and ultimately that it was
caused by a slow initializer in wx.Choice() when the choices are
loaded when the widget is created.  For some reason, moving the
load after the widget is created is significantly faster.  This
change reduces my startup time to just under 4 seconds.

Further speedup could be had by using lazy initialization of the
controls.  But the controls are too bound up in the loaded data
to make this simple.  Maybe I will attack it later.

There is still a significant delay when closing the window, but I
haven't tracked what causes it.  Maybe it is caused just by
destroying all these pin controls.

In the process of making this change, I wanted to simplify the
number of locations that bothered to copy the pinNames list and,
to support lazy loading, to try to keep the same list in all
pinChoice controls.  I noticed that all the pinChoice controls
already have the same parameters passed to the addPinChoice
function which makes them redundant and confusing.  I removed the
extra initializers and just rely on pinNames as the only list
option in addPinChoice for now.  Maybe this flexibility is needed
for some reason later, but I can't see a purpose for it now.

Notes by reviewer Traumflug:

First of all, which "trick"? That's an excellent code
simplification and if this happens to make startup faster (it
does), all the better.

Measured startup & shutdown time here (click window close as soon
as it appears):

  Before:                With this commit:
  real    0m4.222s       real    0m3.780s
  user    0m3.864s       user    0m3.452s
  sys     0m0.084s       sys     0m0.100s

As the speedup was far more significant on the commit author's
machine, it might be a memory consumption issue (leading to
swapping on a small RAM machine). Linux allows to view this in
/proc/<pid>/status.

         Before:          Now:
VmPeak:	  708360 kB     708372 kB
VmSize:	  658916 kB     658756 kB
VmHWM:	   73792 kB      73492 kB
VmRSS:	   73792 kB      73492 kB
VmData:	  402492 kB     402332 kB

Still no obvious indicator, but a 300 kB smaller memory footprint
is certainly nice.
This commit is contained in:
Phil Hord 2016-08-17 19:06:59 -04:00 committed by Markus Hitter
parent 36f54adb7f
commit 9d42fa4ac1
4 changed files with 16 additions and 27 deletions

View File

@ -3,7 +3,6 @@
import wx
from configtool.page import Page
from configtool.data import pinNames
class DisplayPage(wx.Panel, Page):
@ -48,7 +47,7 @@ class DisplayPage(wx.Panel, Page):
for k in ('DISPLAY_RS_PIN', 'DISPLAY_RW_PIN', 'DISPLAY_E_PIN',
'DISPLAY_D4_PIN', 'DISPLAY_D5_PIN', 'DISPLAY_D6_PIN',
'DISPLAY_D7_PIN'):
tc = self.addPinChoice(k, "", pinNames, True, 200)
tc = self.addPinChoice(k, 200)
self.pinbox.Add(tc)
self.pinbox.AddSpacer((5, 5))
sz.Add(self.pinbox, pos = (3, 1))

View File

@ -2,7 +2,8 @@
import wx
from configtool.decoration import Decoration
from configtool.data import reInteger, reFloat, offsetChLabel, offsetTcLabel
from configtool.data import (reInteger, reFloat, offsetChLabel, offsetTcLabel,
pinNames)
class Page:
@ -90,29 +91,19 @@ class Page:
return lsz
def addPinChoice(self, name, choiceVal, pins, allowBlank , labelWidth):
def addPinChoice(self, name, labelWidth):
lsz = wx.BoxSizer(wx.HORIZONTAL)
st = wx.StaticText(self, wx.ID_ANY, self.labels[name],
size = (labelWidth, -1), style = wx.ALIGN_RIGHT)
st.SetFont(self.font)
lsz.Add(st, 1, wx.TOP, offsetChLabel)
if allowBlank:
opts = ["-"] + pins
else:
opts = pins
ch = wx.Choice(self, wx.ID_ANY, choices = opts, name = name,
style = wx.CB_SORT)
ch = wx.Choice(self, wx.ID_ANY, name = name, style = wx.CB_SORT)
ch.SetBackgroundColour(self.deco.getBackgroundColour())
ch.SetFont(self.font)
ch.AppendItems(["-"] + pinNames)
ch.Bind(wx.EVT_CHOICE, self.onChoice)
self.choices[name] = ch
try:
sv = self.pinNames.index(choiceVal)
except:
sv = 0
ch.SetSelection(sv)
lsz.Add(ch)
return lsz

View File

@ -1,7 +1,6 @@
import wx
from configtool.page import Page
from configtool.data import pinNames
class PinoutsPage(wx.Panel, Page):
@ -79,7 +78,7 @@ class PinoutsPage(wx.Panel, Page):
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlPin)
sbox.Add(tc)
elif ctype == 2:
tc = self.addPinChoice(k, "", pinNames, True, labelWidth)
tc = self.addPinChoice(k, labelWidth)
sbox.Add(tc)
else:
cb = self.addCheckBox(k, self.onCheckBox)
@ -98,7 +97,7 @@ class PinoutsPage(wx.Panel, Page):
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlPin)
sbox.Add(tc)
elif ctype == 2:
tc = self.addPinChoice(k, "", pinNames, True, labelWidth)
tc = self.addPinChoice(k, labelWidth)
sbox.Add(tc)
else:
cb = self.addCheckBox(k, self.onCheckBox)
@ -117,7 +116,7 @@ class PinoutsPage(wx.Panel, Page):
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlPin)
sbox.Add(tc)
elif ctype == 2:
tc = self.addPinChoice(k, "", pinNames, True, labelWidth)
tc = self.addPinChoice(k, labelWidth)
sbox.Add(tc)
else:
cb = self.addCheckBox(k, self.onCheckBox)
@ -136,7 +135,7 @@ class PinoutsPage(wx.Panel, Page):
tc = self.addTextCtrl(k, labelWidth, self.onTextCtrlPin)
sbox.Add(tc)
elif ctype == 2:
tc = self.addPinChoice(k, "", pinNames, True, labelWidth)
tc = self.addPinChoice(k, labelWidth)
sbox.Add(tc)
else:
cb = self.addCheckBox(k, self.onCheckBox)
@ -147,7 +146,7 @@ class PinoutsPage(wx.Panel, Page):
sz.Add(sbox, pos = (1, 7))
k = "STEPPER_ENABLE_PIN"
tc = self.addPinChoice(k, "", pinNames, True, labelWidth + 20)
tc = self.addPinChoice(k, labelWidth + 20)
sz.Add(tc, pos = (3, 1))
sz.AddSpacer((10, 10), pos = (4, 1))
@ -157,7 +156,7 @@ class PinoutsPage(wx.Panel, Page):
sz.Add(cb, pos = (5, 1), flag = wx.ALIGN_CENTER_HORIZONTAL)
k = "PS_ON_PIN"
tc = self.addPinChoice(k, "", pinNames, True, labelWidth)
tc = self.addPinChoice(k, labelWidth)
sz.Add(tc, pos = (3, 3))
k = "PS_INVERT_ON"
@ -165,15 +164,15 @@ class PinoutsPage(wx.Panel, Page):
sz.Add(cb, pos = (5, 3), flag = wx.ALIGN_CENTER_HORIZONTAL)
k = "PS_MOSFET_PIN"
tc = self.addPinChoice(k, "", pinNames, True, labelWidth)
tc = self.addPinChoice(k, labelWidth)
sz.Add(tc, pos = (7, 3))
k = "SD_CARD_SELECT_PIN"
tc = self.addPinChoice(k, "", pinNames, True, labelWidth)
tc = self.addPinChoice(k, labelWidth)
sz.Add(tc, pos = (3, 7))
k = "DEBUG_LED_PIN"
tc = self.addPinChoice(k, "", pinNames, True, labelWidth)
tc = self.addPinChoice(k, labelWidth)
sz.Add(tc, pos = (5, 7))
self.SetSizer(sz)

View File

@ -70,7 +70,7 @@ class SensorsPage(wx.Panel, Page):
sz.Add(bsz, pos = (1, 3))
k = "MCP3008_SELECT_PIN"
tc = self.addPinChoice(k, "", pinNames, True, labelWidth)
tc = self.addPinChoice(k, labelWidth)
sz.Add(tc, pos = (2, 1))
self.SetSizer(sz)