[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