[Python-Dev] Speed up function calls
Neal Norwitz
nnorwitz at gmail.com
Tue Jan 25 00:37:04 CET 2005
On Mon, 24 Jan 2005 03:11:05 -0500, Raymond Hettinger <python at rcn.com> wrote:
>
> Replacing METH_O and METH_NOARGS seems straight-forward, but
> METH_VARARGS has much broader capabilities. How would you handle the
> simple case of "O|OO"? How could you determine useful default values
> (NULL, 0, -1, -909, etc.)?
I have a new version of the patch that handles this condition.
I pass NULLs for non-existant optional parameters. In your
case above, the arguments passed would be:
(obj, NULL, NULL)
This is handled pretty cleanly in the callees, since it is
pretty common to initialize optional params to NULL.
> If you solve the default value problem, then please also try to come up
> with a better flag name than METH_ARGS which I find to be indistinct
> from METH_VARARGS and also not very descriptive of its functionality.
> Perhaps something like METH_UNPACKED would be an improvement.
I agree METH_ARGS is a poor name. UNPACKED is fine with me.
If I don't hear a better suggestion, I'll go with that.
> > The drawbacks are:
> > * the defn of the MethodDef (# args) is separate from the function
> defn
> > * potentially more error prone to write C methods???
>
> No worse than with METH_O or METH_NOARGS.
I agree, plus the signature changes if METH_KEYWORDS is used.
I was interested if others viewed the change as better, worse,
or about the same. I agree with /F that it could be a disaster
if it really is more error prone. I don't view the change as
much different. Do others view this as a real problem?
> If speed is the main advantage being sought, it would be worthwhile to
> conduct more extensive timing tests with a variety of code and not using
> a debug build. Running test.test_decimal would be a useful overall
> benchmark.
I was hoping others might try it out and see. I don't have access
to Windows, Mac, or other arches. I only have x86 and amd64.
It would also be interesting to test this on some real world code.
I have tried various builtin functions and methods and the gain
seems to be consistent across all of them. I tried things like
dict.get, pow, isinstance. Since the overhead is fairly constant,
I would expect functions with more arguments to have an even
better improvement.
> In theory, I don't see how you could improve on METH_O and METH_NOARGS.
> The only saving is the time for the flag test (a predictable branch).
> Offsetting that savings is the additional time for checking min/max args
> and for constructing a C call with the appropriate number of args. I
> suspect there is no savings here and that the timings will get worse.
I think tested a method I changed from METH_O to METH_ARGS and could
not measure a difference. A beneift would be to consolidate METH_O,
METH_NOARGS, and METH_VARARGS into a single case. This should
make code simpler all around (IMO).
> In all likelihood, the only real opportunity for savings is replacing
> METH_VARARGS in cases that have already been sped-up using
> PyTuple_Unpack(). Those can be further improved by eliminating the time
> to build and unpack the temporary argument tuple.
Which this patch accomplishes.
> Even then, I don't see how to overcome the need to set useful default
> values for optional object arguments.
Take a look at the updated patch (#2). I still think it's pretty clean and an
overall win. But I'd really like to know what others think. I also implemented
most (all?) of METH_O and METH_NOARGS plus many METH_VARARGS, so
benchmarkers can compare a difference with and without the patch.
Neal
More information about the Python-Dev
mailing list