[Python-Dev] Re: a serious threat to 2.3's speed? (original) (raw)

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

callfunction fastfunction docall extdocall updatekeywordargs updatestarargs 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