Hi Robert,
this change:
+ if self.base.type is list_type:
+ function = "__Pyx_GetItemInt_List"
...
+static INLINE PyObject *__Pyx_GetItemInt_List(
PyObject *o, Py_ssize_t i, int is_unsigned) {
+ if (likely(0 <= i && i < PyList_GET_SIZE(o))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ else return __Pyx_GetItemInt_Generic(o, i, is_unsigned);
+}
does not handle the case that the 'list' might be None. Ticket 166 already
deals with this, but I think this is actually worth discussing, as I would
assume that it leads to a crash here.
http://trac.cython.org/cython_trac/ticket/166
I think that a little set of short inline helper functions that check a
value for Py_None and raise the appropriate exception for a given context
would be nice to have.
I doubt that a check for Py_None will kill performance in this kind of
optimisation, especially since the compiler will be able to see the value
in many cases (e.g. after the first check for None that exits for an
exception). Even in loops, most processors can remember the result of such
a check and adjust their branch prediction accordingly, so that this will
cost us a cycle or something in that order.
Removing these None checks later on is another optimisation, but it's a
feature compared to a potential crash. Maybe we could add a tristate
attribute to entries that tells us if a variable (a) is not, (b) may be or
(c) is definitely None, all but (a) needing such a check, and (c) being
worth knowing in some cases. Even without complete flow analysis, this can
be decided for single-assignment cases (which are definitely common,
especially for container types).
Stefan
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev