On Nov 16, 2008, at 1:38 AM, Stefan Behnel wrote:

> Hi,
>
> Robert Bradshaw wrote:
>> On Nov 15, 2008, at 1:17 PM, Aaron DeVore wrote:
>>
>>> I'm trying to use PyDict_Next to iterate over a dict in a way  
>>> that is
>>> identical to this statement:
>>> for k, v in d.items():
>>>     # do stuff with key and value
>>
>> Yes, declare them to be PyObject* rather than object. Then you'll
>> have to do all refcounting manually (as you would have had to do
>> anyways, as PyDict_Next doesn't decref its input). However, I doubt
>> iterating over the dict manually like that will be a significant
>> speed increase than the basic Python way of doing it.
>
> I ran timeit on this:
>
> ---------------------------------------
> def items(d):
>     for k,v in d.items():
>         pass
>
> def iteritems(d):
>     for k,v in d.iteritems():
>         pass
>
> def dictnext(d):
>     cdef Py_ssize_t pos = 0
>     cdef PyObject* pk = NULL
>     cdef PyObject* pv = NULL
>
>     while PyDict_Next(d, &pos, &pk, &pv):
>         k = <object>pk
>         v = <object>pv
> ---------------------------------------
>
> With a 1000 item dict in Py2.5, it gives me this:
>
>     $ python2.5 -m timeit -s '...' 'items(d)'
>     10000 loops, best of 3: 98.3 usec per loop
>     $ python2.5 -m timeit -s '...' 'iteritems(d)'
>     10000 loops, best of 3: 50.8 usec per loop
>     $ python2.5 -m timeit -s '...' 'dictnext(d)'
>     10000 loops, best of 3: 26.8 usec per loop
>
> So, yes, there is a speedup. It may not be worth it for small  
> dicts, but
> the code is not so bad that it's not worth a 50% speedup for larger  
> dicts.

I stand happily corrected. I though there would be some improvement,  
but not near that much. I am particularly surprised at the poor  
performance of items vs iteritems, I guess the allocation is killing  
us here.

- Robert


_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to