Hello Elefterios, On 12/11/2011 09:28 PM, Elefterios Stamatogiannakis wrote: > I'm exploring pypy's code so as to speed up callbacks from C code, so as to > speed up sqlite module's UDF. > > I have some questions: > > - What are the differences between ctypes, rawffi and ffi. Where should each > one of them be used?
_rawffi and _ffi are pypy-specific modules which expose the functionalities of libffi. _rawffi is old and slow, while _ffi is new and designed to be JIT friendly. However, at the moment of writing not all features of _rawffi have been ported to _ffi yet, that's why we need to keep both around. ctypes is implemented on top of _rawffi/_ffi. The plan for the future is to kill _rawffi at some point. > - I see that ctypes is build on top of rawffi and ffi. If one wishes to work > around ctypes (so as to not have ctype's overhead) which of the rawffi or ffi > should he use? Which of the two is faster at runtime? if possible, you should use _ffi. Note that so far with _ffi you can only call functions, but e.g. you cannot define a callback. If you are interested in this stuff, you might want to look at the ffistruct branch, which adds support for jit-friendly structures to _ffi. Note that the public interface of _ffi is still fluid, it might change in the future. E.g., right now pointers are represented just by using python longs, but we might want to use a proper well-typed wrapper in the future. > - How can i create a null pointer with _ffi? As I said above, right now pointers are passed around as Python longs, so you can just use 0 for the null pointer. > And some remarks: > > By only modifying pypy's sqlite module code, i managed to speed up sqlite's > callbacks by 30% (for example there is a "for i in range(nargs)" line in > _sqlite3. _convert_params, which is a hot path). that's nice. Patches are welcome :-) > Also the following line in _ctypes/function.py ._wrap_callable > > args = [argtype._CData_retval(argtype.from_address(arg)._buffer) > for argtype, arg in zip(argtypes, args)] > > Occupies a large percentage of the overall callback time (around 60-70%). yes, I think that we never looked at performance of ctypes callback. Good spot :-). In other parts of ctypes there are hacks and shortcuts for performances. E.g., in _wrap_result we check whether the result type is primitive, and in that case we just avoid to call _CData_retval. Maybe it's possible to introduce a similar shortcut there. > Assuming that pypy JITs all of the above callback code. Is it a problem having > all these memory allocations for each callback (my test does 10M callbacks)? > Is there a way to avoid as much as possible all these memory allocations. > > Right now CPython runs my test (10M callbacks) in 1.2 sec and pypy needs from > 9 to 14 secs. I suspect that the large spread of pypy's run times are due to > GC. I think it's "simply" because we never optimized callbacks. When I ported ctypes from _rawffi to _ffi I got speedups up to 100 times faster. In case of callbacks I expect a minor gain, because the JIT cannot inline across them, but I still think there is room for lots of improvements. If you are interested in trying it, I'll be more than glad to help you :) ciao, Anto _______________________________________________ pypy-dev mailing list [email protected] http://mail.python.org/mailman/listinfo/pypy-dev
