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.
Stefan
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev