[Python-Dev] Re: a serious threat to 2.3's speed?
Duncan Booth
duncan at rcp.co.uk
Thu Dec 11 11:35:57 EST 2003
Skip Montanaro <skip at pobox.com> wrote in
news:16344.38379.89674.176847 at montanaro.dyndns.org:
> Python's function call machinery is complex, mostly in the argument
> marshalling area I think. Take a look in Python/ceval.c at
>
> call_function
> fast_function
> do_call
> ext_do_call
> update_keyword_args
> update_star_args
>
> If Jim's compiler doesn't yet support any of varargs, keyword args,
> calling C functions or calling bound method objects, I suspect his
> code is more streamlined.
I've been working on my own implementation of Python for .Net, although
I've now emailed Jim to ask if I can help him with his since he seems to be
further on that I am with my version.
The way I was planning to do function calls (and had partially implemented
it), was to have an IPyCallable interface, and a set of classes that
implement that interface.
The interface includes methods:
PyObject __call__();
PyObject __call__(PyObject arg1);
PyObject __call__(PyObject arg1, PyObject arg2);
PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3);
PyObject __call__(PyObject[] args);
PyObject __call__(PyObject[] args, PyDict keywordArgs);
Concrete classes exist for functions and for bound methods taking 0, 1, 2,
3 or more arguments. The constructor for a function object takes a
delegate, a list of argument names and a list of defaults.
The idea was that, say you had a function taking 3 arguments and you call
it with 3 arguments, the call can be passed straight through without doing
any checking at all for default args or keyword args, so one virtual call
then a delegate call. If you call it with fewer arguments the earlier
overloads simply add in the missing defaults. This should allow pretty well
all calls to be streamlined so you only pay for the overhead of variable
number of arguments or keywords if you actually use them in the call, and
even then you don't have a string to interpret at runtime.
I was planning to create function wrappers at runtime, so that a method
that took say a string and an integer would be wrapped by a static function
taking three PyObject arguments and casting them appropriately before
forwarding to the wrapped method. So a Python call to a method would get
directed through the function object which calls the delegate to the
wrapper which does any necessary casts and calls the underlying method. In
practice some of these nested calls should be optimisable by the JIT.
Anyway, that was my scheme. I wonder what Jim's is.
--
Duncan Booth duncan at rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
More information about the Python-Dev
mailing list