Stefan Behnel wrote:
> Nick Joyce, 22.02.2010 21:11:
>   
>> The current PyAMF code is littered with PyDict_* calls so I am in the
>> process of refactoring it to make use of this syntactic sugar.
>>
>> When I generate the C code (using Cython 0.12.1) for the above function,
>> the resulting C code will use PyDict_SetItem for the assignment
>> statement but will use PyObject_GetItem on line 6. I have attached a
>> snippet of the generated C [pyobject_getitem.c].
>>     
>
> To me, the reason why this wasn't done before is that the Python semantics
> often are not what one really wants here. The corresponding code that uses
> PyDict_GetItem() is faster when the key is found, but it is very
> inefficient when the key is not found. The function would simply return
> NULL in this case, which is easy and fast to test for in C code. Usually,
> when I needed pure speed here, I needed it for the failure case, so I used
> a direct C-API call anyway.
>
> Robert is right in suggesting that it might not even be worth it. Even a
> virtual call to the tp_getitem slot (which is a pretty direct result of the
> PyObject_GetItem() call) is likely not that much slower than a call to
> PyDict_GetItem(), given the overhead of emulating the Python semantics
> around the call. Only benchmarking can tell if this brings more than a
> negligible 4% speedup 'on average'.
>
> It would certainly bring much more if Cython could deduce what the result
> is used for afterwards, and then reduce the true Python semantics to what
> is really needed. E.g. this code:
>
>     cdef dict d = ...
>     try:
>         item = d['test']
>     except KeyError:
>         item = d['test'] = some_value
>
> could be reduced to this pseudo code:
>
>     try:
>         if d is None:
>              raise TypeError(...)
>         item = PyDict_GetItem(d, 'test')
>         if item is NULL:
>             goto except_handler
>         Py_INCREF(item)
>     except KeyError:
>         except_handler:
>         PyDict_SetItem(d, some_value)
>         Py_INCREF(some_value)
>         item = some_value
>
> But that's certainly not trivial with the current compiler infrastructure.
> It would be possible to see that a KeyError is caught around a dict access,
> so that it would no longer be necessary to actually raise the KeyError in
> the first place.
>
> Then again, this could happen:
>
>     try: ...
>     except KeyError:
>          print sys.exc_info()
>
> Well, well, Python ...
>
>   
How about just optimizing "d.get(key[, default])" if it isn't already 
for this case, and document that [] is slower?

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

Reply via email to