[Python-Dev] Re: Prospective Peephole Transformation

Andrew MacIntyre andymac at bullseye.apana.org.au
Tue Feb 22 13:13:08 CET 2005


Fredrik Lundh wrote:

> it could be worth expanding them to
> 
>     "if x == 1 or x == 2 or x == 3:"
> 
> though...
> 
> C:\>timeit -s "a = 1" "if a in (1, 2, 3): pass"
> 10000000 loops, best of 3: 0.11 usec per loop
> C:\>timeit -s "a = 1" "if a == 1 or a == 2 or a == 3: pass"
> 10000000 loops, best of 3: 0.0691 usec per loop
> 
> C:\>timeit -s "a = 2" "if a == 1 or a == 2 or a == 3: pass"
> 10000000 loops, best of 3: 0.123 usec per loop
> C:\>timeit -s "a = 2" "if a in (1, 2, 3): pass"
> 10000000 loops, best of 3: 0.143 usec per loop
> 
> C:\>timeit -s "a = 3" "if a == 1 or a == 2 or a == 3: pass"
> 10000000 loops, best of 3: 0.187 usec per loop
> C:\>timeit -s "a = 3" "if a in (1, 2, 3): pass"
> 1000000 loops, best of 3: 0.197 usec per loop
> 
> C:\>timeit -s "a = 4" "if a in (1, 2, 3): pass"
> 1000000 loops, best of 3: 0.225 usec per loop
> C:\>timeit -s "a = 4" "if a == 1 or a == 2 or a == 3: pass"
> 10000000 loops, best of 3: 0.161 usec per loop

Out of curiousity I ran /F's tests on my FreeBSD 4.8 box with a recent 
checkout:

$ ./python Lib/timeit.py -s "a = 1" "if a in (1, 2, 3): pass"
1000000 loops, best of 3: 0.247 usec per loop
$ ./python Lib/timeit.py -s "a = 1" "if a == 1 or a == 2 or a == 3: pass"
1000000 loops, best of 3: 0.225 usec per loop
$ ./python Lib/timeit.py -s "a = 2" "if a in (1, 2, 3): pass"
1000000 loops, best of 3: 0.343 usec per loop
$ ./python Lib/timeit.py -s "a = 2" "if a == 1 or a == 2 or a == 3: pass"
1000000 loops, best of 3: 0.353 usec per loop
$ ./python Lib/timeit.py -s "a = 3" "if a in (1, 2, 3): pass"
1000000 loops, best of 3: 0.415 usec per loop
$ ./python Lib/timeit.py -s "a = 3" "if a == 1 or a == 2 or a == 3: pass"
1000000 loops, best of 3: 0.457 usec per loop
$ ./python Lib/timeit.py -s "a = 4" "if a in (1, 2, 3): pass"
1000000 loops, best of 3: 0.467 usec per loop
$ ./python Lib/timeit.py -s "a = 4" "if a == 1 or a == 2 or a == 3: pass"
1000000 loops, best of 3: 0.488 usec per loop

I then applied this patch:
--- Objects/tupleobject.c.orig  Fri Jun 11 05:28:08 2004
+++ Objects/tupleobject.c       Tue Feb 22 22:10:18 2005
@@ -298,6 +298,11 @@
         int i, cmp;

         for (i = 0, cmp = 0 ; cmp == 0 && i < a->ob_size; ++i)
+               cmp = (PyTuple_GET_ITEM(a, i) == el);
+       if (cmp)
+               return cmp;
+
+       for (i = 0, cmp = 0 ; cmp == 0 && i < a->ob_size; ++i)
                 cmp = PyObject_RichCompareBool(el, PyTuple_GET_ITEM(a, i),
                                                    Py_EQ);
         return cmp;

Re-running the tests yielded:

$ ./python Lib/timeit.py -s "a = 1" "if a in (1, 2, 3): pass"
1000000 loops, best of 3: 0.234 usec per loop
$ ./python Lib/timeit.py -s "a = 1" "if a == 1 or a == 2 or a == 3: pass"
1000000 loops, best of 3: 0.228 usec per loop
$ ./python Lib/timeit.py -s "a = 2" "if a in (1, 2, 3): pass"
1000000 loops, best of 3: 0.239 usec per loop
$ ./python Lib/timeit.py -s "a = 2" "if a == 1 or a == 2 or a == 3: pass"
1000000 loops, best of 3: 0.36 usec per loop
$ ./python Lib/timeit.py -s "a = 3" "if a in (1, 2, 3): pass"
1000000 loops, best of 3: 0.241 usec per loop
$ ./python Lib/timeit.py -s "a = 3" "if a == 1 or a == 2 or a == 3: pass"
1000000 loops, best of 3: 0.469 usec per loop
$ ./python Lib/timeit.py -s "a = 4" "if a in (1, 2, 3): pass"
1000000 loops, best of 3: 0.475 usec per loop
$ ./python Lib/timeit.py -s "a = 4" "if a == 1 or a == 2 or a == 3: pass"
1000000 loops, best of 3: 0.489 usec per loop

-------------------------------------------------------------------------
Andrew I MacIntyre                     "These thoughts are mine alone..."
E-mail: andymac at bullseye.apana.org.au  (pref) | Snail: PO Box 370
        andymac at pcug.org.au             (alt) |        Belconnen ACT 2616
Web:    http://www.andymac.org/               |        Australia


More information about the Python-Dev mailing list