This Post Is Not About Python

Pure Python is generally a slow language. Written for performance, it will often be around 40-50 times slower than C, and Python “written for performance” is Python that is very straightforward and does not use many of its features. Python code that has a couple of methods on inherited classes, maybe a non-trivial decorator, and some __getattr__ or similar features can slow down multiplicative factors beyond the 40-50 slower very quickly.

This post is not about Python.

Pure Python also lacks the ability to use more than one CPU very effectively in a coordinated fashion. Python has a variety of solutions to this problem, but this is one of the cases where there is a “variety of solutions” precisely because none of them are full solutions to the problem. That is, if one of these was really the solution, there wouldn’t be a “variety”. Fortunately, there are some problems in the world where this is no big deal; for example, while it isn’t necessarily the nicest thing to dedicate a full OS process to every HTTP request, it has proved to be a model that can scale for quite a ways before becoming a problem.

This post is not about Python.

Python is a very flexible language, but you pay for that flexibility in the runtime. If you use that flexibility, though, it can be a very good deal. It’s a very nice language to work in, it’s just that you need to keep an eye on your performance needs when setting out to use it. Of course, that’s true of any language, it’s just Python being one of the slower languages in common use, and making it relatively easy to stack several slowdowns on top of each other, just means you need to pay extra special attention to Python.

This post is not about Python.

In particular, one of the things to be aware of when it comes to Python performance is that given that you’re starting out at 40-50x slowdowns versus faster compiled languages like C, if you do have need for high performance, it may not even be theoretically possible to recover through Python’s multiprocessing or threading capabilities, because even perfect utilization from perfectly parallel code, that also never suffers from any sort of contention on reference counts or anything like that, would still require upwards of a 32 to 64 core system just to match what a compiled language can run on a single processor. And you’re never going to get a perfect linear speedup on pure Python code all the way up to that many cores, any more than you can anywhere else. Removing the GIL will not change this, because it’s not a GIL problem.

This post is not about Python.

All that warning aside, though, modern computers are very, very fast. Human time is valuable, including both programmers and users, and if using Python means faster development and more rapid delivery, then it can still be an enormous win. Abstract performance considerations aren’t everything. There’s a lot of tasks in the world where the computers are so absurdly fast and the real performance needs so low by comparison that the performance issues of Python are completely irrelevant in that particular context. This was true even when Python was running on 200MHz 32-bit machines with a few megabytes of memory; it is obviously even moreso true on modern hardware.

It’s just worth double-checking before you start with Python that you won’t encounter any problems, or that any problems you encounter will be amenable to one of Python’s several solutions to speeding up bits of code by using something other than Python, since those solutions have very strong “grains” to them. Careful analysis of the data flow is also necessary as you can lose the theoretical gains of dropping into a faster language if you are constantly moving data back and forth, especially complicated structures; I’ve certainly heard of a people putting a lot of effort into this only to find they get almost no win because of this problem, or even seeing performance loss.

This post is not about Python.

Most of what is said above is objectively true. You may be able to quibble around the edges, because there are always fringe issues to quibble over, but it will be only fiddling around the edges. One can not argue Python into running faster than it does. Arguing about the details of the text above, while inevitable if this is ever posted to an aggregation site, is also missing the point. Even if I was grotesquely wrong about something, it would still be missing the point.

The question I have for you is, do you perceive this as an attack? Are you processing this with your political brain? If you associate with Python, are you classifying me as an outsider to be attacked? If you do not associate with Python, and especially if you are not a big fan, are you classifying me as friend and standing ready to defend against counterattacks?

What this post is about is the engineering risks of being a fan.

Engineering is about solving problems. At the highest level, tool choice decisions are complicated. You need to consider what engineers you have on hand, what skills they have, what skills they may be able to acquire, what the business needs are, what the costs of a whole range of different possible solutions are, where those costs are themselves usually ranges of risk rather than rigid promises that this approach will cost exactly $1,353,374.54, etc. And I mean this only as a partial list intended to make you think about not just “does this language have a particular library”, but all the way up and down what a senior engineer ought to be considering.

In the process of making that decision, you are going to find that every option has downsides. Every single one. If you haven’t found them, you aren’t looking hard enough.

And you will be crippled as a senior engineer if you are unable to calmly evaluate the downsides of your favorite options because you see them as attacks on the target of your fandom. You can’t think this way as an engineer. You need to be evaluating things based on what they are, not what you wish they were. You can’t live in a world of perfect, unassailable technologies that can do everything and have no flaws versus the vile, useless technologies that have no redeeming values whatsoever1.

I chose Python as my target here mostly because it so happens to be the problem I see the most often online. That’s a reflection of where I happen to hang out, not an absolute fact about Python. The goals of this post are served best if I push the most popular buttons. But as this post rather frequently says, this post is not about Python.

You can write something similar about any useful technology. They’ve all got downsides, and if you fancy yourself an engineer, and especially either a senior engineer right now or a senior engineer in potentia, you need to be able to calmly think about them.

I have seen projects die because their first engineers chose the language they were fans of, even when a calm and sober assessment of the technology should have revealed from day one that it was not an appropriate choice and there was no way it could handle the stresses of the project (be it computational load or architectural load) under the given budget constraints2. I have seen many other projects stagger on like a zombie, unable to be killed, but unable to proceed onward, because of the wrong choice of tool. This post focused on programming language but database technology is another thing I’ve seen frequently go wrong, perhaps even moreso than programming language.

Engineers are not fans of technologies.

They are also, of course, not dispassionate Vulcans who get every assessment perfectly rationally correct at all times, trivially proved by how much even relatively rational engineers can disagree with each other.

But engineers should never be fans.

Are you a fan?


  1. Sometimes things do end up more-or-less in the “vile” category, because there is no bound on how bad a technology can be. There are bounds on the positive side, though. No technology can ever be the one-size-fits-all optimum solution to every problem. Still, they need to arrive in the “vile pile” due to evidence and a calm analysis of the situation, not an emotional reaction. ↩︎

  2. In fact, just in the time between drafting this and posting it publicly, I believe I’ve encountered another project that is likely to either die or require massive rework in the next couple of years due to a catastrophic language fanboy. If I’m really “lucky” I’ll end up involved, as one of the few people who can understand the language in question. ↩︎