[Pyrex] Pyrex optimization chitchat

Phillip J. Eby pje at telecommunity.com
Wed Jan 14 22:02:11 CET 2004


At 12:34 PM 1/14/04 -0800, Paul Prescod wrote:

>For instance, PySequence_SetItem, PyList_SetItem and PyList_SETITEM all
>handle references a little bit different. So you probably have to have
>syntax that says whether references are borrowed, stolen, lent or given by
>the function.

Good point.


>And I don't know if Greg cares much about performance issues. It obviously
>was not his highest priority (which is good!).

Well, the very first 'primes.pyx' example certainly emphasized speed.  And, 
speed is the "other" reason for using Pyrex besides accessing C 
libraries.  And, often, the reason for accessing a C library in the first 
place is for speed...  So it seems that all the roads tend to end back up 
at performance.  :)


> > For getting Pyrex into the Python core, it'd be a lot less
> > hassle to add a new e.g. 'sets.pxi' file than it would to hack the
> > Pyrex code generator again.
>
>Yes. But on the other hand, we need to keep two things in perspective.
>First, this is just a performance hack. Sets (for example) work with Pyrex
>out of the box just by virtue of its fallback to PyObject_GetItem. Second,
>how often are new types added to the Python core with their own high
>performance APIs? It isn't as if tomorrow someone is likey to add a
>PyQueue_GetItem or PyBag_GetItem.

That's true.  I'm just also thinking that it would move Pyrex to a more 
microkernel architecture, pulling its internal tables out into the language 
itself.  At that point, the language's operators, allocation, and so forth 
would all just be generics.


> > E.g. something like
> >
> > cdef pytype sequence int PySequence_Check(object):
> >     __getitem__ = object PySequence_GetItem(object,int)
> >     __contains__ = int PySequence_In(object,object) except -1
> >     #... etc.
>
>Interesting idea. Reminiscent of C++ type overlpading (in that it is done at
>compile time rather than runtime the way it is in Python). It might also be
>cool to define type conversions between arbitrary types in this way.

Hm.  I don't think I'd want C++-style type conversions being applied, 
though.  I'd rather say, e.g.

cdef dict foo = dict(bar)

instead of expecting Pyrex to convert 'bar' to a 'dict' on its own.


>The other obvious slow bit in PyRex is stuff like this:
>
>     /* "/Users/pprescod/code/bisect/rxbisect0.pyx":13 */
>     __pyx_2 = __Pyx_GetName(__pyx_b, "len"); if (!__pyx_2) {__pyx_filename =
>__pyx_f[0]; __pyx_lineno = 13; goto __pyx_L1;}
>     __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0];
>__pyx_lineno = 13; goto __pyx_L1;}
>     Py_INCREF(__pyx_v_a);
>     PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_a);
>     __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4)
>{__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; goto __pyx_L1;}
>     Py_DECREF(__pyx_2); __pyx_2 = 0;
>     Py_DECREF(__pyx_3); __pyx_3 = 0;
>     Py_DECREF(__pyx_v_hi);
>     __pyx_v_hi = __pyx_4;
>     __pyx_4 = 0;
>     goto __pyx_L2;
>   }
>   __pyx_L2:;

Yes.  And that also does the whole allocate-and-intern-the-string dance.


>There are a few different ways to handle this depending on how important you
>feel it is that len(foo) really always call __builtins__.len(foo) even if
>the type of "foo" is known. If the dynamicity of "len" is untouchable then
>you could define Pyrex modules like "listoptimizations" and
>"dictoptimizations" with functions like "listlen" and "dictlen" that could
>be statically bound rather than dynamically bound.

Oh, I see your point...  I was mainly thinking that Pyrex should require e.g.

cdef public object len

in a module in order to allow a builtin to be overridden.  To put it 
another way, use of a global name that doesn't have an explicit definition 
in the module source, should be considered fair game for 
replacement/optimization.

AFAIK, this is the way Python's headed anyway.  There was supposed to be a 
warning about it added in 2.3, although there were some issues that caused 
the warning to be dropped before the 2.3 final release.





More information about the Pyrex mailing list