From: wander.lairson <wan...@gm...> - 2011-05-10 10:10:29
|
2011/5/9 Emmanuel Blot <ebl...@gm...>: > Hello, > > We have been facing performance issues with PyUSB. > > As our code can run with both pyftdi/libftdi/libusb (Py/C/C) or pyftdi/pyusb/libusb (Py/Py/C), we have profiled the code and observed that the stack based on the native libftdi librarie performs far better than the one based on the pyusb stack. It was quite surprising to see a huge difference between both stack, as libftdi really is a thin wrapper on top of libusb. > > With the help of the Python profiling modules, we have been able to find the culprit: a sub-optimized call to the read() and write() functions. These functions accept an 'interface' parameter, which can be of different type - such as an interface number, None or an core.Interface class instance. > > When this parameter is not an core.Interface object, the read() and write() methods invoke -through the get_interface() method - a time-costly interface resolution processing. This routine is - relative to the other calls - deadly slow, and is repeated for every single read() or write() call. > > Replacing the interface index (an integer) with a core.Interface object shows a tremendous improvement of the average transmission time, with final performances very close to the native C implementation of the libftdi library. > > I'm not sure this hint is documented somewhere, but I thing it could be part of the FaQ or something, with an reference from the Python documentation string, as selecting the proper parameter type for the read() and write() 'interface' shows a large performance boost. > The root of all trouble is the internal _ResourceManager.get_configuration method, that returns an interface object. If I change it to return the interface number instead, maybe the performance gets improved, either with an Interface object or interface number as parameter. Going to check that. Wander |