Python is darn fast (was: How fast is Python)

Michele Simionato mis6 at pitt.edu
Sun Aug 24 16:38:49 CEST 2003


I finally came to the conclusion that the exceeding good performance
of Psyco was due to the fact that the function was called a million
times with the *same* argument. Evidently Psyco is smart enough to
notice that. Changing the argument at each call
(erfc(0.456) -> i/1000000.0) slows down Python+Psyco at 1/4 of C speed. 
Psyco improves Python performance by an order of magnitude, but still it 
is not enough :-(

I was too optimistic!

Here I my numbers for Python 2.3, Psyco 1.0, Red Hat Linux 7.3, 
Pentium II 366 MHz:

$ time p23 erf.py
real    0m3.245s
user    0m3.164s
sys     0m0.037s

This is more than four times slower than optimized C:

$ gcc erf.c -lm -O3
$ time ./a.out
real    0m0.742s
user    0m0.725s
sys     0m0.002s
 
Here is the situation for pure Python

$time p23 erf.jy
real    0m27.470s
user    0m27.162s
sys     0m0.023s

and, just for fun, here is Jython performance:

$ time jython erf.jy
real    0m44.395s
user    0m42.602s
sys     0m0.389s

----------------------------------------------------------------------

$ cat erf.py
import math
import psyco
psyco.full()

def erfc(x):
    exp = math.exp

    p  =  0.3275911
    a1 =  0.254829592
    a2 = -0.284496736
    a3 =  1.421413741
    a4 = -1.453152027
    a5 =  1.061405429

    t = 1.0 / (1.0 + p*x)
    erfcx = ( (a1 + (a2 + (a3 +
                          (a4 + a5*t)*t)*t)*t)*t ) * exp(-x*x)
    return erfcx

def main():
    erg = 0.0

    for i in xrange(1000000):
        erg += erfc(i/1000000.0)

if __name__ == '__main__':
    main()

--------------------------------------------------------------------------

# python/jython version = same without "import psyco; psyco.full()"

--------------------------------------------------------------------------

$cat erf.c
#include <stdio.h>
#include <math.h>

double erfc( double x )
{
    double p, a1, a2, a3, a4, a5;
    double t, erfcx;

    p  =  0.3275911;
    a1 =  0.254829592;
    a2 = -0.284496736;
    a3 =  1.421413741;
    a4 = -1.453152027;
    a5 =  1.061405429;

    t = 1.0 / (1.0 + p*x);
    erfcx = ( (a1 + (a2 + (a3 +
     (a4 + a5*t)*t)*t)*t)*t ) * exp(-x*x);

    return erfcx;
}

int main()
{
    double erg=0.0;
    int i;

    for(i=0; i<1000000; i++)
    {
       erg = erg + erfc(i/1000000.0);
    }

    return 0;
}

Michele Simionato, Ph. D.
MicheleSimionato at libero.it
http://www.phyast.pitt.edu/~micheles/
---- Currently looking for a job ----




More information about the Python-list mailing list