Live data from Hacker News

Why Python Is Slow: Looking Under the Hood

jakevdp.github.io

91–100 of 156 posts

Re: Why Python Is Slow: Looking Under the Hood

#91
post #77

Earlier quoted context omitted.

I'm not sure your results are typical. In microbenchmarks, Perl is 2-125x slower than C++: http://benchmarksgame.alioth.debian.org/u32/benchmark.php?te... And Java is quite a bit faster than Perl too: http://benchmarksgame.alioth.debian.org/u32/benchmark.php?te... Perl isn't really that fast. It's faster than Python in most cases, but gets beat by Lua pretty consistently: http://benchmarksgame.alioth.debian.org/u32/b…

For a general-purpose problem, Perl won't be particularly fast. For a Perl-type problem (scanning and parsing big files), Perl is very fast. Doing a Perl-type problem in a general-purpose language would be considerably slower. However, Python or others will perform much better in the "can I read my own code six months later" benchmark.

I don't know why I always have to chip in on "perl is unreadable lol" comments, but over the last 8 years apart from a steady trickle of C coding here and there the bulk of my dayjob has moved around from C/Verilog, then I discovered Ruby, then Perl/R/Python, to full-time Python now.

It's true that unsupervised, weak coders using perl turn out worse code than in other languages. But it really doesn't take much to produce good code if you have a tiny bit of supervision/discipline (which stems mostly from 80% of perl tutorials on the web are teaching 1997-era perl anti-patterns). And/or if you happen to be a stronger programmer in something else, hopefully you stumble across perlcritic and modern perl patterns more quickly.

Well-written Moose code involves less boilerplate, the declarative nature and composability of classes, types and data members with free type/value validation is a delight to maintain, and results in more robust code with a lot fewer silent failures (or objects happily chugging along silently with invalid state) than typical Python classes.

Of course, now that I can't use Moose and the Python community actively seems to discourage the very thought of relying on any superset of core Python OO features like enthoughts' traits package - I really want to revisit static/stronger typed programming languages for large projects. So it feels like I've come full-circle in my programming career...

Re: Why Python Is Slow: Looking Under the Hood

#92
post #80

Please forgive my ignorance, but why can't Python just be compiled into assembly like C? The compiler should be able sift through the code and see that "x=1" is an integer, or converts to a float when "x=x+1.0". If I'm doing something like counting from 1 to 10 and summing the count, why can't this be compiled to run the same speed as C? Obviously since it's interpreted, but when I'm done with development, why can't…

Python is similar in terms of dynamic features to Ruby. I'm actually working on an ahead of time "a static as possible" Ruby compiler.

You certainly can compile languages this dynamic, the problem is that the "simple" way of compiling it doesn't result in very fast code, because you essentially end up mimicking what the interpreters/vms do very closely, and a lot of what ends up being executed will be things like method lookups which are reasonably well optimized in the interpreters.

The problem boils down to the ability to "change the world" at almost any point.

E.g. in Ruby (don't know about Python), you can come back from an eval() call (or load or require) and find that the expression 1 + 1.0 results in the string "two", or will send you an insulting e-mail, because you can even override Fixnum#+.

Now, there's a lot that can be done to infer typing for these types of languages well enough that you can get away with slow-path fallbacks for the rare cases where users does something stupid (like override Fixnum#+) and run faster most of the time, but it's a lot of extra effort.

Re: Why Python Is Slow: Looking Under the Hood

#93
post #77

Earlier quoted context omitted.

I'm not sure your results are typical. In microbenchmarks, Perl is 2-125x slower than C++: http://benchmarksgame.alioth.debian.org/u32/benchmark.php?te... And Java is quite a bit faster than Perl too: http://benchmarksgame.alioth.debian.org/u32/benchmark.php?te... Perl isn't really that fast. It's faster than Python in most cases, but gets beat by Lua pretty consistently: http://benchmarksgame.alioth.debian.org/u32/b…

For a general-purpose problem, Perl won't be particularly fast. For a Perl-type problem (scanning and parsing big files), Perl is very fast. Doing a Perl-type problem in a general-purpose language would be considerably slower. However, Python or others will perform much better in the "can I read my own code six months later" benchmark.

> For a Perl-type problem (scanning and parsing big files), Perl is very fast.

I think it's a matter of what you're comparing it to.

Compared to using Perl for a general-purpose problem, Perl for scanning/parsing is fast.

Compared to scanning/parsing with C, Perl is not fast.

    $ ruby -e '1.upto(1000000) { |n| puts "This is line number #{n}" }' > file
    $ time perl -ne 'print if /number 12345/' 
I gave Perl every possible advantage here. I didn't actually even write any Perl except a regular expression, which is delegated immediately to C. I didn't even write the loop in Perl, I like the Perl main() function handle that. And still the C program is almost 10x faster.

Note: these test runs are from Linux. On OS X the Perl results were almost the same, but "grep" was unexplainably way slower. It seems to hang after it's already dumped all of its output. Basically grep on OS X appears to be badly broken somehow.

Re: Why Python Is Slow: Looking Under the Hood

#94

A related question is: why is Perl so fast? Quite a few years ago I wrote a little Runge-Kutta solver in Perl for some simulation work. It seemed like a good idea at the time. The equations of motion had to be integrated over a very long time, and it could take hours for a single run (still much faster than the Monte Carlo it was being used to do a sanity-check on). I re-wrote everything in C++, and picked up less th…

If you only got a 2x speedup there is something wrong. A more usual number for Perl is about 100x slower than C++ for numerical code. Perl isn't very different than Python in this regard. e.g. on the shootout on the n-body benchmark, Perl is about as fast as Python, and 125x slower than C++.

Re: Why Python Is Slow: Looking Under the Hood

#95
Unfortunately this blog post is misleading and uninformed. Python and the related other slow dynamic languages perl, php, and ruby are slow not because the dynamic type checks, branches and indirections are costly, but because they are badly written. They are just inefficient and poor interpreters, with bad ops and data structures. In comparison efficient dynamic languages like lisp, scheme, lua or javascript and many others not so well known do exist. Mine, potion, is also in the lua category, and not in the slow PPPR (python, perl, php, ruby) category.

The seminal paper about efficient dynamic interpreters is Ertl's "The Structure and Performance of Efficient Interpreters" http://www.complang.tuwien.ac.at/papers/ertl%26gregg03jilp.p...

The abstract is: "Interpreters designed for high general-purpose performance typically perform a large number of indirect branches (3.2%–13% of all executed instructions in our benchmarks). These branches consume more than half of the run-time in a number of configurations we simulated. We evaluate how accurate various existing and proposed branch prediction schemes are on a number of interpreters, how the mispredictions affect the performance of the interpreters and how two different interpreter implementation techniques perform with various branch predictors. We also suggest various ways in which hardware designers, C compiler writers, and interpreter writers can improve the performance of interpreters."

My own input to this is that the GC, the JIT, the calling convention and esp. the size of the datastructures and ops do matter more, than eliminating the type checks.

Re: Why Python Is Slow: Looking Under the Hood

#96
post #80

Please forgive my ignorance, but why can't Python just be compiled into assembly like C? The compiler should be able sift through the code and see that "x=1" is an integer, or converts to a float when "x=x+1.0". If I'm doing something like counting from 1 to 10 and summing the count, why can't this be compiled to run the same speed as C? Obviously since it's interpreted, but when I'm done with development, why can't…

> The compiler should be able sift through the code and see that "x=1" is an integer, or converts to a float when "x=x+1.0".

The short version is "no, it shouldn't".

The longer version is that, viewing Python's runtime class memberships as "types", the type system it would represent is not one for which inference without explicit declarations is generally decidable, so an AOT compiler for unmodified, unrestricted Python that is expected to infer types at runtime simply would not be possible.

You could AOT compile it into C code with a lot of runtime metadata and indirections -- but that would probably have worse performance than the existing interpreter.

> Way back when, you could get a BASIC compiler to turn your interpreted BASIC code into assembly.

Well, yeah, BASIC is actually structurally quite close to assembly. Its not a dynamically-typed multiparadigm language like Python.

Re: Why Python Is Slow: Looking Under the Hood

#97
post #80

Please forgive my ignorance, but why can't Python just be compiled into assembly like C? The compiler should be able sift through the code and see that "x=1" is an integer, or converts to a float when "x=x+1.0". If I'm doing something like counting from 1 to 10 and summing the count, why can't this be compiled to run the same speed as C? Obviously since it's interpreted, but when I'm done with development, why can't…

What you describe is pretty much what functional languages with strong static typing, like Haskell, Scala, and Ocaml do. Works very well for examples like you gave: "x = 1", "x = x + 1.0". For expressions similar to these, inferring the types (int, float) works very well. But things get much more complex very fast, and then the compiler requires the programmer to tell it what types things are. Then there is the appro…

If Python had the same amount of time and energy put into it that JavaScript does from Google and Mozilla it'd be willing to bet it'd be a lot faster.

Re: Why Python Is Slow: Looking Under the Hood

#98
post #80

Please forgive my ignorance, but why can't Python just be compiled into assembly like C? The compiler should be able sift through the code and see that "x=1" is an integer, or converts to a float when "x=x+1.0". If I'm doing something like counting from 1 to 10 and summing the count, why can't this be compiled to run the same speed as C? Obviously since it's interpreted, but when I'm done with development, why can't…

> The compiler should be able sift through the code and see that "x=1" is an integer, or converts to a float when "x=x+1.0". The short version is "no, it shouldn't". The longer version is that, viewing Python's runtime class memberships as "types", the type system it would represent is not one for which inference without explicit declarations is generally decidable, so an AOT compiler for unmodified, unrestricted Pyt…

Its hard to be worse than an interpreter. 100X slower than compiled code is typical. Whatever 'metadata and indirection' your C target has, it seems likely to be 10X better than interpreted, easily.

Re: Why Python Is Slow: Looking Under the Hood

#99
post #95

Unfortunately this blog post is misleading and uninformed. Python and the related other slow dynamic languages perl, php, and ruby are slow not because the dynamic type checks, branches and indirections are costly, but because they are badly written. They are just inefficient and poor interpreters, with bad ops and data structures. In comparison efficient dynamic languages like lisp, scheme, lua or javascript and man…

The numerous Common Lisp implementations out there would agree with you.

Re: Why Python Is Slow: Looking Under the Hood

#100
post #91
post #77

Earlier quoted context omitted.

For a general-purpose problem, Perl won't be particularly fast. For a Perl-type problem (scanning and parsing big files), Perl is very fast. Doing a Perl-type problem in a general-purpose language would be considerably slower. However, Python or others will perform much better in the "can I read my own code six months later" benchmark.

I don't know why I always have to chip in on "perl is unreadable lol" comments, but over the last 8 years apart from a steady trickle of C coding here and there the bulk of my dayjob has moved around from C/Verilog, then I discovered Ruby, then Perl/R/Python, to full-time Python now. It's true that unsupervised, weak coders using perl turn out worse code than in other languages. But it really doesn't take much to pro…

Well said :). I like Perl but when I write it I'm aiming above all for readability
Post reply on HN