Live data from Hacker News

Why Python Is Slow: Looking Under the Hood

jakevdp.github.io

61–70 of 156 posts

Re: Why Python Is Slow: Looking Under the Hood

#61
post #50

I don't understand why is it compared to C, when it can be compared to Perl or PHP, which are also dynamically typed, interpreted, etc, but much faster.

1. Because TFA is about scientific computing

2. And in that context (and most others), the difference between Perl, PHP and CPython is basically non-existent, you might get 2x on one bench, half on the other

Re: Why Python Is Slow: Looking Under the Hood

#62

Earlier quoted context omitted.

> pypy -mtimeit 'sum(xrange(1, 100000001))' 10 loops, best of 3: 153 msec per loop however the context of TFA is scientific computing, hence pypy being ignored/dismissed

We can do it this was if needed. http://clementbera.wordpress.com/2013/06/19/optimizing-pharo...

Having an FFI is not relevant, Pypy has an excellent FFI already[0].

You can't interface with the existing SciPy ecosystem which expects the CPython API, which is the reason why pypy doesn't matter in scientific computing.

[0] inspired by LuaJIT and usable from both CPython and PyPy: https://cffi.readthedocs.org/en/release-0.8/

Re: Why Python Is Slow: Looking Under the Hood

#63

cPython does alot of work for just about any piece of code. Just a small handful of things: 1. everything's a hash (object data, variable lookup, etc). jmoiron wrote a great article on the topic http://jmoiron.net/blog/whats-going-on/ 2. refcounting introduces overhead for every variable access 3. loops are making all kinds of function calls to __iter__, next(), and catching StopIteration, which makes it hard to have…

Well, it's hard to write an interpreter with the performance of, say, MRI Ruby.

I'm getting poe'd so I'll check: you're being sarcastic, right?

Re: Why Python Is Slow: Looking Under the Hood

#64
post #43

Is it just me who sees a large chunk of these as flaws in the Python implementation as opposed to the Python language ? Dynamic typing can often be optimized at the compilation stage - and yes, Python has a compilation stage - this particular example is basic type inference, for example. Even more complex examples can be optimized by emitting specialized versions for the types that the compiler can see it will be cal…

Is it just me who sees a large chunk of these as flaws in the Python implementation as opposed to the Python language? There are a number of design decision in python language that makes it inherently hard to write a fast python implementation.

Ah, the right answer!

There are lots of languages where variables are dynamically typed that can be compiled and optimized with a JIT compiler. In Python, though, any code can mess with any data, using "setattr". You can find all the variables in another module and mess with them at run time, using their names as strings. At compile time, the compiler can't detect that's going to happen.

This is sometimes called the Guido von Rossum Memorial Boat Anchor.

So Python implementations usually have to assume the worst case. Google's attempt at a faster, compatible Python, "Unladen Swallow", was an embarrassing failure. PyPy manages to get past that, but at a huge cost in JIT compiler complexity. After 12 years of work, PyPy is finally shipping stable versions and starting to get some use. It's been all uphill for the PyPy developers, though.

It's kind of sad. Python never achieved its full potential because of the speed problem. Google ended up developing Go because Python was too slow.

Re: Why Python Is Slow: Looking Under the Hood

#65
post #43

Is it just me who sees a large chunk of these as flaws in the Python implementation as opposed to the Python language ? Dynamic typing can often be optimized at the compilation stage - and yes, Python has a compilation stage - this particular example is basic type inference, for example. Even more complex examples can be optimized by emitting specialized versions for the types that the compiler can see it will be cal…

Is it just me who sees a large chunk of these as flaws in the Python implementation as opposed to the Python language? There are a number of design decision in python language that makes it inherently hard to write a fast python implementation.

He said "a large number of" though, not "all".

Re: Why Python Is Slow: Looking Under the Hood

#66

Earlier quoted context omitted.

Well, it's hard to write an interpreter with the performance of, say, MRI Ruby.

I'm getting poe'd so I'll check: you're being sarcastic, right?

:3

(do a little research...you might be pleasantly surprised)

Re: Why Python Is Slow: Looking Under the Hood

#67
post #14
post #5

Why, oh, why does CPython bother keeping refcounts for small integers? Sure, it lets you make pretty graphs with [sys.getrefcount(i) for i in range(1000)]... but that's an extra memory read and write on every instruction that uses an integer. I can only imagine that not only are these extra instructions, but they're extra instructions that kill pipelining, if the interpreter needed to do "a = 1; b = 1; c = 1" for ins…

Python also keeps refcounts for other objects that shouldn't be garbage collected such as None, True, and False. The reason being to prevent having certain objects that need to be refcounted and certain objects that don't. Otherwise, C code would be littered with if statements like the below: if (number 256) { decrement_refcount(number); }

To be fair, you'd expect that to live in decrement_refcount.

Re: Why Python Is Slow: Looking Under the Hood

#68
post #36
post #13

Earlier quoted context omitted.

Once again, you can't implement this without specializing every call site that invokes Py_INCREF or Py_DECREF, or in other words, "1 conditional branch per object access everywhere."

You are right, but cost is probably very low. The conditionality of the branch doesn't matter if it's correctly predicted. On a modern processor, a correctly predicted branch-not-taken is usually indistinguishable from free unless you're already front-end constrained, which is rare for an interpreter. A correctly predicted branch-taken costs the same as a unconditional branch. This is essentially why a JIT can be alm…

Right, so the question becomes whether a branch mispredict is cheaper than simply refcounting an object that already lives in L1 cache (by virtue of having any of its words accessed). For Intel Sandy Bridge, this is 14-18 cycles for the mispredict, or ~4+4 for the L1 word read/write. Now the question becomes how often that mispredict will occur, and there's no real way to measure this short of an implementation.

Re: Why Python Is Slow: Looking Under the Hood

#69

Is it just me who sees a large chunk of these as flaws in the Python implementation as opposed to the Python language ? Dynamic typing can often be optimized at the compilation stage - and yes, Python has a compilation stage - this particular example is basic type inference, for example. Even more complex examples can be optimized by emitting specialized versions for the types that the compiler can see it will be cal…

You are technically correct. A Sufficiently Smart Compiler(TM) could theoretically optimize python code.

However certain language features can be inherently difficult to optimize. Most of it's over my head, but headius has written some great articles as part of his experience of implementing ruby on the jvm. http://blog.headius.com/2012/09/avoiding-hash-lookups-in-rub...

Re: Why Python Is Slow: Looking Under the Hood

#70

"it's slow" "just write a C extension" "but then why use Python?"

Because the C extension you need has probably already been written.

This is the same kind of network effect that drove Perl usage for some many years. CPAN had it. Even if I didn't want to use Perl, CPAN was overwhelmingly compelling.

Python has since taken on that mantle.

Post reply on HN