Why is my Python version slower than my Perl version?


Question

I've been a Perl guy for over 10 years but a friend convinced me to try Python and told me how much faster it is than Perl. So just for kicks I ported an app I wrote in Perl to Python and found that it runs about 3x slower. Initially my friend told me that I must have done it wrong, so I rewrote and refactored until I could rewrite and refactor no more and ... it's still a lot slower. So I did a simple test:

i = 0
j = 0

while (i < 100000000):
    i = i + 1
    j = j + 1

print j

$ time python python.py
100000000

real 0m48.100s
user 0m45.633s
sys 0m0.043s

my $i = 0;
my $j = 0;

while ($i < 100000000) {
    ++$i; # also tested $i = $i + 1 to be fair, same result
    ++$j;
}

print $j;

$ time perl perl.pl
100000000

real 0m24.757s
user 0m22.341s
sys 0m0.029s

Just under twice as slow, which doesn't seem to reflect any of the benchmarks I've seen ... is there a problem with my installation or is Python really that much slower than Perl?

1
13
2/26/2018 9:49:18 AM

The nit-picking answer is that you should compare it to idiomatic Python:

  • The original code takes 34 seconds on my machine.
  • A for loop (FlorianH's answer) with += and xrange() takes 21.
  • Putting the whole thing in a function reduces it to 9 seconds!
    That's much faster than Perl (15 seconds on my machine)!
    Explanation: Python local vars are much faster than globals.
    (For fairness, I also tried a function in Perl - no change)
  • Getting rid of the j variable reduced it to 8 seconds:

    print sum(1 for i in xrange(100000000))

Python has the strange property that higher-level shorter code tends to be fastest :-)

But the real answer is that your "micro-benchmark" is meaningless. The real question of language speed is: what's the performance of an average real application? To know that, you should take into account:

  • Typical mix of operations in complex code. Your code doesn't contain any data structures, function calls, or OOP operations.

  • A large enough codebase to feel cache effects — many interpreter optimizations trade memory for speed, which is not measured fairly by any tiny benchmark.

  • Optimization opportunities: after you write your code, IF it's not fast enough, how much faster can you easily make it?

    E.g. how hard is it to offload the heavy lifting to effecient C libriries?

PyPy's benchmarks and Octane are good examples of what realistic language speed benchmarks look like.

If you want to talk number crunching, Python IS surprisingly popular with scientists. They love it for the simple pseudo-math syntax and short learning curve, but also for the excellent numpy library for array crunching and the ease of wrapping other existing C code.

And then there is the Psyco JIT which would probably run your toy example well under 1 second, but I can't check it now because it only works on 32-bit x86.
EDIT: Nowdays, skip Psyco and use PyPy which a cross-platform actively improving JIT.

51
5/23/2017 12:30:30 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon