In snooping around wx, I found that methods were bound like so:
def GetPrintMode(self, *_args, **_kwargs):
val = apply(wxc.wxPyApp_GetPrintMode,(self,) + _args, _kwargs)
return val
This looks extremely inefficient because:
* apply has to be looked up in the __builtins__ dict
* a new tuple has to be allocated as a result of the tuple addition
* wxc has to be looked up in the globals dictionary
* the func name has to be looked up in the module's dictionary
I tried some different implementations and got the following timings for
invocations of the method:
$ python overhead.py 100000
reps: 100000
2.2.2 (#1, Nov 26 2002, 16:14:37)
[GCC 3.2 (Mandrake Linux 9.0 3.2-1mdk)]
14.2 seconds for FooOld
10.6 seconds for FooNew1
9.8 seconds for FooNew2
3.2 seconds for FooNew3
FooOld is the current approach. FooNew3 is simply this:
class FooNew3:
GetPrintMode = wxc.wxPyApp_GetPrintMode
This approach eliminates all those extra steps I outlined above.
The code is here:
http://chuckesterbrook.com/files/python/wx/method-overhead/
I realize that as the function implementations increase in complexity,
the call overhead becomes less of an issue. On the other hand, the C++
native code is so much faster than Python bytecode, that this overhead
may still be significant for a lot of methods.
I think it's worth it to cut out the overhead and make things snappier.
If this can be applied everywhere, then all apps and wxPython users
will benefit!
Robin/Patrick/whoever: Is this an improvement that could be applied
universally? (I can't think why not, but maybe I'm missing
something...) And can it made in the 2.4.x series?
···
--
Chuck
http://ChuckEsterbrook.com