[pypy-dev] ctypes - PyPy 1.8 slower than Python 2.6.5

Sébastien Volle sebastien.volle at gmail.com
Mon Feb 13 15:22:08 CET 2012


Thank you for your help Antonio. It seems a little indentation problem in
the modified arp.py file you attached makes the main() loop to return after
a single packet. I attached the updated version.

The actual new figures are:
CPython: ~580ms (~310ms with initial version)
PyPy: ~1120ms (~1300ms with initial version)

So, the manual cast of array to c_void_p makes the program around 2x slower
on CPython, and only marginally faster on PyPy. PyPy spends now most its
time in pointer.py:_cast_addr().

I might try with a bigger pcap file and try to investigate a bit on my own
when I get the occasion. On a related note, I wish I could just use the
pcapy module for this particular project, which is actually way faster than
ctypes wrappers, at least with CPython, but it doesn't build for pypy
(missing things in sysconfig I believe).

Thank you for your time.

Regards,
Sébastien


2012/2/13 Antonio Cuni <anto.cuni at gmail.com>

> Hello Sébastien,
>
>
> On 02/13/2012 01:33 PM, Sébastien Volle wrote:
>
>  During my investigations, I turned out that using ctypes, PyPy 1.8 is
>> 4x slower than CPython 2.6.5.
>> After looking at the PyPy buglist, it's seems there are couple open issues
>> about ctypes so I figured I would ask you guys first before filing a new
>> bug.
>>
>> I'm pretty new to ctypes and pypy so I'm not sure I understand what's
>> going.
>> My program seems to spend a lot of time in ctypes/function.py:_convert_**
>> args
>> though, has the following profile trace demonstrates:
>>
>
> this is indeed a problem (or, better, a missing feature) in pypy's ctypes
> implementation.
>
> PyPy can make ctypes calls fast only in a set of "supported cases": in
> that case, ctypes calls take a fast path which is actually very fast, while
> in all the others it takes a slow path which is actually very slow :-/.
>
> I looked at your code and I realized that there is one common case in
> which we fail to take the fast path, and this happens when we pass a ctypes
> array to a function which expects a pointer. This means that in your code
> all the calls to c.memcmp are slow.
>
> This is something that we should really fix. In the meantime, you can work
> around the issue by manually casting the array to a c_void_p before calling
> the function; e.g.::
>
>                        xx = cast(offset_eth.dst, c_void_p)
>                        yy = cast(eth_brd, c_void_p)
>                        if c.memcmp(xx, yy, 6) != 0:
>
> In addition, I should point out that both in pypy and cpython the code
> executed inside functions is much faster than the code executed at module
> level: so, I put most of the code in arp.py inside a function called
> main(), which is then called and timed.
>
> You can find my quickly hacked arp.py attached here. With my changes, it
> now takes 0.13ms vs 440.5ms on CPython, and 0.77ms vs 1092.71ms on PyPy.
>
> On this particular test CPython is still faster than PyPy, however it
> might simply be that the JIT doesn't have enough time to warmup. Could you
> please try it on a larger cap file so that it runs at least for e.g. 5
> seconds?
>
> ciao,
> Anto
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/pypy-dev/attachments/20120213/21482740/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: arp.py
Type: application/octet-stream
Size: 5622 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/pypy-dev/attachments/20120213/21482740/attachment.obj>


More information about the pypy-dev mailing list