11 ms·
Python is fundamentally not designed to be faster because it leaks a lot of stuff that’s inherently slow that real world code depends on. That’s mutable interpr
by the_mitsuhiko 6y ago
Python is fundamentally not designed to be faster because it leaks a lot of stuff that’s inherently slow that real world code depends on. That’s mutable interpreter frames, global interpreter locks, shared global state, type slots, the C ABI.
The only way to speed it up would be to change the language.
- Liquid_Fire 6y agoYou could say the same about JavaScript, but with very heavy investment there are now several implementations that have improved its performance significantly. Also see PyPy, which manages to squeeze a lot more performance out of Python for many use cases without changing the language.
- awestroke 6y agoJS does not have mutable interpreter frames, global interpreter locks, shared global state, type slots, the C ABI.
- dfox 6y agoJS and Python has essentially same data model with everything being at least conceptually built out of dicts. And well, most JS implementations do not have GIL because they are not multithreaded at all.
- baq 6y agotrue and doesn't matter in the context. you can't change (or inspect) the stack frame as an object. you can kind of look at it with Error().stack. this allows the JS JIT to make assumptions that a python compiler simply cannot.
- dfox 6y agoMost of the things that real application code (ie. not something like debugger) can accomplish by modifying or event inspecting frame objects are going to depend on various things that are documented as CPython implementation details. Also JS runtime that supports some kind of debugger interface has to solve the same class of problems. And the most straightforward solution is not even that complex: you simply have to track when some kind of assumption gets broken and then fall back to interpretation or recompile the relevant code (the most complex part of that probably is converting the native stack frame back into interpreter stack frame, which you have to be able to do anyway in order to even expose it to user code for it to be able to modify it). In fact I think that there are many relatively simple modifications that would make CPython significantly faster, but many such things conflict with each other in ways that make the resulting complexity not worth it.
- ihnorton 6y agoThe principal developer of Pyston commented on the JavaScript comparison recently [1]: > This is a common view but I've never heard it from someone who has tried to optimize Python. Personally I think that Python is as much more dynamic than JavaScript as JavaScript is than C. [1] https://news.ycombinator.com/item?id=23247618 https://news.ycombinator.com/item?id=23247618
- arc776 6y agoThe thing about Javascript is it's actually a very simple language. You can make a lot of guarantees and this means performance patterns can be implied. Ultimately JS can be reduced to a very tight engine. This is not possible with Python, it's just too dynamic.
- stephc_int13 6y agoJavascript or PHP were not designed to be fast as well. Oh, wait...
- jerf 6y agoMost languages designed in that era were not designed to be fast, and none of them were designed to be fast on 2020-era processors. The former is because this was the era of exponential CPU growth, and the latter because as good as many of these language designers were, none of them were psychic. I'm pretty sure both Guido for Python and Larry for Perl were explicitly aware of the impossibility of designing for processors that wouldn't exist for 20 years, though digging up quotes to that effect would be quite difficult. A mantra of that era is "There are no slow languages, only slow implementations." I, for one, consider this mantra to be effectively refuted. Even if there is a hypothetical Python interpreter/compiler/runtime/whatever that can run effectively as fast as C with no significant overhead (excepting perhaps some reasonable increase in compile time), there is no longer any reason to believe that mere mortal humans are capable of producing it, after all the effort that has been poured into trying, as document by the original link. Whatever may be true for God or superhuman AIs, for human beings, there are slow languages that build intrinsically slow operations into their base semantics.
- robertlagrant 6y agoWell, Javascript has similar dynamism and yet v8 exists. I'm not saying the investment will ever happen for Python, but I do think it's possible for humans.
- formerly_proven 6y agoThe problem is not jitting pure Python code. PyPy does that and it's quite good at doing it. The problem is exactly what mitsuhiko says, and lots of Python apps use some or all of these features implicitly (through the native extensions used by many common dependencies). Sure, some of this madness can be accessed from Python itself, but that's also the case for JS, where you can do certain things, which will slow down your code greatly because the JIT can't work with it.
- deleted 6y ago[deleted]
- rmrfstar 6y agoPython is the duct tape of programming languages. Never the best tool if you have strict performance requirements, but so damn versatile it will never go away. Cython does need better docs though, the steep learning curve means it is under-utilized.
- centimeter 6y agoAnd like things made out of duct tape, I’ve never found anything made using python that actually functioned well.
- NortySpock 6y agoDid it function well enough for your purposes? Because I don't need it to be hermetically-sealed perfection, I just need my python code to spit out a good result when I throw it at a problem; nevermind that it took a few seconds to spin up or needs more memory than a perfectly crafted C program.
- centimeter 6y agoMost python apps don’t function well enough for my purposes.
- coldtea 6y agoThen you have bizarro purposes, because Python is in production all over the world, in business critical, billion at stakes, systems...
- centimeter 6y agoOr maybe you just have very low standards.
- coldtea 6y agoWhat part of "business critical, billions at stake, systems" conveys "low standards"? And if Google, Amazon, NASA, etc (all places where Python is used heavily), are not high enough for you, what exactly are your standards?
- mikepurvis 6y agoIt's true that there are certain non-negotiable costs there, and projects like Mercurial have invested heavily in trying to figure out how to make Python start up faster, and basically hit a brick wall (see: https://www.mercurial-scm.org/wiki/PerformancePlan https://www.mercurial-scm.org/wiki/PerformancePlan). That said, for a lot of other projects which haven't yet looked, there may be some low-hanging fruit. For example, I was doing some looking at this recently on a highly pluggable workspace build tool called colcon [1], and found that of 5+ seconds of startup time, I could save about 1 second with "business logic" changes (adding caching to a recursive operation), another 1 second by switching some filesystem operations to use multiprocessing, and about 1.5 seconds from making some big imports (requests, httpx, sanic) happen lazily on first use. [1]: https://github.com/colcon/colcon-core/issues/398 https://github.com/colcon/colcon-core/issues/398
- overgard 6y agoI don't think that's really true, those things are definite challenges, but PyPy is still significantly faster than CPython while (afaik) allowing that sort of stuff to go on. If you wanted C/Rust level performance than yeah, you need to redesign the language, but if you just want an interpreter that runs 5-10x faster than what they have now? Both doable and has been done.
- kissgyorgy 6y agoPyPy is faster at the price of higher memory usage, which is not always desirable.
- the_mitsuhiko 6y ago> PyPy is still significantly faster than CPython while (afaik) allowing that sort of stuff to go on First of all that's only true when it managed to jit the code, secondly only until you try to do any of those slow things. For instance the C ABI emulation they have both cannot support all of CPython and wrecks performance. The same is true if you try to do fancy things with sys._getframe which a lot of code does in the wild (eg: all of logging). In addition PyPy has to do a lot of special casing for all the crazy things CPython does. I recommend looking into the amount of engineering that went into it.
- overgard 6y agoYeah, but most code doesn't use things like sys.getframe? I don't see the problem here. You can choose whether those features are worth the speed penalty or not. And yeah the C ABI is slow, but that's true of practically every language. Again, it's a choice of if you use those things or not. That doesn't devalue making other parts of the language faster.
- Rochus 6y agoPyPy is about four times faster than CPython (https://speed.pypy.org/ https://speed.pypy.org/) which is not that much compared to the effort. Node.js is about 13 times faster (https://benchmarksgame-team.pages.debian.net/benchmarksgame/which-programs-are-fastest.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/...).
- ilyagr 6y agoI found the following talks by Armin Romacher very informative on these topics (C API, why python is more difficult to speed up than JS). https://youtu.be/qCGofLIzX6g https://youtu.be/qCGofLIzX6g https://youtu.be/IeSu_odkI5I https://youtu.be/IeSu_odkI5I I wish these were the things Python 3 addressed, rather than Unicode. I guess it's much more obvious in hindsight than back when Python 3 was designed.
- carabiner 6y ago(OP is Armin)
- baq 6y agounicode absolutely had to be done. it'd be even more insane to leave strings as they were. maybe if you never venture outside of 7 bits it's only pain with negative ROI, but trust me the world has more languages than english and first-class support for unicode strings as just strings is a must. it was a painful transition but a necessary one. all other modern languages simply started there (and they're old enough to have a beer, too).
- mumblemumble 6y agoI would guess that, if Python 3 hadn't addressed Unicode, Python would never have come to a place where so many people are worried about its performance. Python's still a great language for the things it was being designed for back in the 2000s. But adding decent Unicode support is a big part of what helped it become an attractive language for use cases where I wish it performed better or had better support for parallelism. Natural language processing, for example.
- kec 6y agoHow do you square that assertion with the fact that people clung so hard to python 2 that it took the PSF 12 years to finally kill it?
- mumblemumble 6y agoSome people clung hard to 2. Others flocked to 3. In my direct experience, the only people who waited until the bitter end (and beyond) were ops folks who never had to stray much outside of 7-bit ASCII, and companies with large existing codebases that didn't want to allocate the resources to migrating. Neither of those really have much to do with my assertion that Python 3 attracted new people doing new things.
- snicker7 6y agoPython is ~100x slower than C. There is definitely wiggle room for improvement.
- chrisseaton 6y ago> That’s mutable interpreter frames, global interpreter locks, shared global state, type slots, the C ABI. There's research towards solving all of these problems. > The only way to speed it up would be to change the language. Maybe we just haven't worked out how yet? Nothing you've mentioned is known to be impossible to make fast.
- skohan 6y ago> C ABI Why should this make python slow?
- deleted 6y ago[deleted]
- chrisseaton 6y agoIf you have to meet an existing ABI then you're constrained in how you can optimise.
- Rochus 6y agoHow would you explain then that LuaJIT is so much faster than CPython? Even the interpreter of LuaJIT is much faster. > The only way to speed it up would be to change the language. What specifically? Most of your points are not related to the language. And even current Smalltalk engines are much faster than CPython (see https://github.com/OpenSmalltalk/opensmalltalk-vm https://github.com/OpenSmalltalk/opensmalltalk-vm).
- fanf2 6y agoLua exposes much less of its internals than Python. For example the comment you replied to mentioned stack frames which are not exposed in Lua.
- anonymoushn 6y agoThose are exposed via the built-in debug library, including in luajit.
- fanf2 6y agoOh whoops yes :-) Note that you can only look up variables by their bytecode register number, not by name.
- jashmatthews 6y agoIIRC that uses the Lua C API which LuaJIT supports by fully restoring the interpreter state?
- jashmatthews 6y agoLua doesn’t have assignment as an expression. Lua 5.1 has float as the only numeric type. Lua varargs are easier to implement. Each VM op for Python or Ruby ends up being bigger and having more branches. For Ruby this is quite painful on the numeric types. Branching, boxing and unboxing is far slower than just testing and adding floats in the LuaJIT VM. Due assignment as an expression and things like x = foo(x, x+=1) Ruby, Python and JS all need to copy x into a new VM Register when it’s used. LuaJIT can assume locals aren’t reassigned mid statement and doesn’t need copies.
- jnxx 6y agoThat's really surprising if one considers for a moment how many things Python has in common with Common List, a language which can be compiled to run near C speed (albeit with some sacrifices on safety i.e. "unsafe" optimizations). And if anything, Python 3 has become more similar to Lisp, while running at 1 / 20 of its speed.
- beagle3 6y agoPython does have a lot in common with CL; but the problem with Python is that almost any call you cannot statically inline, which is most of them, can change the semantics of everything else - you've just called math.floor() ; are you sure it wasn't just monkeypatched to assign 7 to all local variables who have an 'x' in their name in the caller's frame? Most of these uses are very rare, but the tail is incredibly long for Python, and the problem is that you can't even compile a "likely normal" and a "here be dragons" versions, and switch only when needed - you need to constantly verify. The same is not true, AFAIK, with Common Lisp - being a lisp1 and having a stronger lexical scope than python does. Shedskin is a Python to C++ compiler that mostly requires the commonly-honoured constrained that a variable is only assigned a single type throughout its lifetime. (And that you don't modify classes after creation, and that you don't need integers longer than machine precision, and ....); While many programs seem to satisfy these requirements on superficial inspection, it turns out that almost all programs violate them in some way (directly or through a library). The probability that Shedskin will manage to compile a program that was not written with Shedskin in mind is almost zero. Nuitka was started with the idea that, unlike shedskin, it will start by compiling the bytecode to an interpreter-equivalent execution (which it does, quite well), to get a minor speed up - and then gradually compile "provably simple enough" things to fast C++; a decade or so later, that's not working out as well as hoped, AFAIK because everything depends on something that violates simplicity.
- nemoniac 6y ago> The same is not true, AFAIK, with Common Lisp - being a lisp1 and having a stronger lexical scope than python does. Common Lisp is a Lisp2.
- arc776 6y agoI completely agree. Everything is baked in to be slow. There is no way around it, I don't think you can write super fast interpreters like with Javascript - I might be wrong, but so far it hasn't happened. For general use cases the performance is fine, but only thanks to the hard work of C/CPython/Cython programmers who give up Python's rich expressibility to gain this performance. It seems like you simply have to use another language to get anything running fast. Having said all that, Pyc seems interesting as it apparently compiles Python. Has anyone had any experience of this?
- chrisseaton 6y ago> There is no way around it What aspects of the language are you convinced cannot be optimised? There's tons of research in this area.
- arc776 6y agoAs the OP states: > mutable interpreter frames, global interpreter locks, shared global state, type slots On top of this, Python is extremely dynamic and nothing can be assured without running through the code. So this leads to needing JITs to improve performance which then give a slow start up time and increased complexity. Even with JIT, Python is just not fast thanks to the above issues and it's overall dynamism. It can be optimised and for sure there's some impressive attempts at doing so. However I don't think pure Python will ever be considered "fast" as these things necessarily get in the way. I highly recommend the two videos posted here that go into more detail as to why there are limits to how far optimisation can go: https://youtu.be/qCGofLIzX6g https://youtu.be/qCGofLIzX6g https://youtu.be/IeSu_odkI5I https://youtu.be/IeSu_odkI5I
- chrisseaton 6y ago> why there are limits to how far optimisation can go I'd challenge the idea that there really are known 'limits'. As I say there's research towards this, these videos are old, and Armin and Seth may not be up to date with all of the literature (in fact I'm sure Seth is not, as he's missing at least one major current Python implementation research project from his blog post.)
- moralsupply 6y agoThat's not correct. Python will never be as fast as hand-optimized assembler, but it certainly can be much (5-10x) faster that what it is right now for most workloads. Pypy is a living proof that it can be done.
- dralley 6y agoYou're arguing with mitsuhiko, he's given entire talks on this subject. https://www.youtube.com/watch?v=qCGofLIzX6g&t=31m44s https://www.youtube.com/watch?v=qCGofLIzX6g&t=31m44s PyPy is faster for pure Python code, but that comes at the expense of having a far slower interface with C code. There's an entire ecosystem built around the fact that while Python itself is slow, it can very easily interface with native code (Numpy, Scipy, OpenCV) with very little overhead. So sure, you can make Python much faster, if you're willing to piss off the very Python users who care the most about performance in the first place (the data science / ML people and anyone else using native extensions).