Hi,

Robert Bradshaw wrote:
> On Nov 16, 2008, at 1:38 AM, Stefan Behnel wrote:
>> 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.

That makes me wonder if it's not worth using such an implementation for

    cdef dict d
    ...
    for (key|value|key,value) in d.iter(keys|values|items)():
        ...

internally - but *only* for the ".iter*()" variants to avoid introducing
problems with dict modification during iteration. That would be a pretty
cool optimisation. The generic loop code we currently generate is huge
compared to a straight call to PyDict_Next().

Maybe a tree transformation could replace the for-loops above with a new
DictLoopNode that would generate the respective code.

Stefan

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

Reply via email to