4 ms·
> It cannot be understated, removing the GIL will be a HUGE deal for Python! It's an ugly wart which has existed for about 30 years I would argue the opposite:
by mumblemumble 4y ago
> It cannot be understated, removing the GIL will be a HUGE deal for Python! It's an ugly wart which has existed for about 30 years
I would argue the opposite: it's the secret to Python's success. It might even be my top example of how "worse is better" plays out in real life.
I agree, the GIL feels like an ugly hack. The software engineer in me wants to hate it so much. And, now that I'm on the far side of a successful transition to a data science role, one might think that I hate it even more, yeah? Because the work I'm doing depends so very heavily on compute performance and parallelism.
But it turns out, nah, I'm coming to like it. It's an ugly hack, but it's the best kind of ugly hack: one that gets the job done.
Because I'm pretty sure that the GIL is the secret sauce that makes Python C extensions work so well. Without it, it would be much more difficult to write safe, correct C extensions. Doing it without introducing race conditions that destroy memory safety would be a black art. So people would probably do it less. And that probably means no robust Python scientific computing or data science ecosystem, because that stuff is all C extensions.
We could instead use a C FFI, like it's done in other languages. Java, for example. But Java having to use an FFI and Python being able to use its C extension mechanism is exactly why Python has eaten all of Java's Wheaties in the data space. The marshaling costs of talking back and forth across that boundary are just too high. Copying goes up, locality of reference goes down, cache misses go up. You saturate the memory bus more quickly. Once you've done that, it doesn't matter how many threads you have running on how many cores. The bottleneck is happening outside the CPU. Top will happily tell you those cores are working hard, but it turns out that what they're working so hard at is sitting around and waiting.
This isn't just theoretical. Last year I replaced a heavily parallelized compute-heavy batch process written in Java with a Python implementation that got the work done in less time despite being single-threaded. Sure, the Python implementation was basically a little scripting on top of a library written in C++, and the Java one was pure Java. But that's kind of the whole point. I also know that, back when I wrote the original Java implementation, I tried the same trick of farming the calculation out to a C++ library, and it actually made the throughput even worse. JNI is a harsh master.
And besides, as others have said, numpy & friends give me most the parallelism I actually need, for free.
Maybe it hurts other people more? Maybe Web developers? But there's a part of me that thinks, if you're trying to do that kind of work at scale, making Python go faster is perhaps barking up the wrong tree. There are plenty of other languages that are statically typed (reducing pointer chasing and branching can increase your throughput without giving Amazon more money in the process) and don't even need a global interpreter lock in the first place because they're not interpreted, either.
- mcherm 4y agoI am not persuaded. I think that C extensions could handle multi-threading more easily or could simply document that they only support single-threaded use. BUT, I had never heard this argument made and I find it a very interesting and insightful one -- thank you for explaining in detail!