[Python-Dev] Special-casing "O"

Martin v. Loewis martin@loewis.home.cs.tu-berlin.de
Fri, 25 May 2001 08:00:47 +0200


> Special-casing the snot out of "O" looks like a winner <wink>:

I have a patch on SF that takes this approach:

http://sourceforge.net/tracker/index.php?func=detail&aid=427190&group_id=5470&atid=305470

The idea is that functions can be declared as METH_O, instead of
METH_VARARGS. I also offer METH_l, but this is currently not used. The
approach could be extended to other signatures, e.g. METH_O_opt_O
(i.e. "O|O").  Some signatures cannot be changed into special-calls,
e.g. "O!", or "ll|l".

In the PyXML test suite, "O" is indeed the most frequent case (72%),
and it is primarily triggered through len (26%), append (24%), and ord
(6%). These are the only functions that make use of the new calling
conventions at the moment. If you look at the patch, you'll see that
it is quite easy to change a method to use a different calling
convention (basically just remove the PyArg_ParseTuple call).

To measure the patch, I use the script

from time import clock

indices = [1] * 20000
indices1 = indices*100
r1 = [1]*60

def doit(case):
    s = clock()
    i = 0
    if case == 0:
        f = ord
        for i in indices1:
            f("o")
    elif case == 1:
        for i in indices:
            l = []
            f = l.append
            for i in r1:
                f(i)
    elif case == 2:
        f = len
        for i in indices1:
            f("o")
    f = clock()
    return f - s

for i in xrange(10):
    print "%.3f %.3f %.3f" % (doit(0),doit(1),doit(2))

Without the patch, (almost) stock CVS gives

2.190 1.800 2.240
2.200 1.800 2.220
2.200 1.800 2.230
2.220 1.800 2.220
2.200 1.800 2.220
2.200 1.790 2.240
2.200 1.790 2.230
2.200 1.800 2.220
2.200 1.800 2.240
2.200 1.790 2.230

With the patch, I get

1.440 1.330 1.460
1.420 1.350 1.440
1.430 1.340 1.430
1.510 1.350 1.460
1.440 1.360 1.470
1.460 1.330 1.450
1.430 1.330 1.420
1.440 1.340 1.440
1.430 1.340 1.430
1.410 1.340 1.450

So the speed-up is roughly 30% to 50%, depending on how much work the
function has to do.

Please let me know what you think.

Regards,
Martin