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
