Live data from Hacker News

Python performance myths and fairy tales

lwn.net

161–170 of 221 posts

Re: Python performance myths and fairy tales

#161
post #158

Earlier quoted context omitted.

Okay, but this is going out of one's way to view the runtime itself as a C program and connect to it with the FFI. For that matter, the notion that the result of `id` ( https://docs.python.org/3/library/functions.html#id ) could sensibly be passed to `from_address` is an implementation detail. This is one reason the language suffers from not having a formal specification: it's unclear exactly how much of this madness…

Except, that sort of thing is important in places like gevent, pytest, and numba, and that functionality isn't easy to replace without a lot of additional language/stdlib work (no sane developer would reach for it if other APIs sufficed). The absurd example of overwriting the literal `10` is "obviously" bad, but your assertion that the interpreter should be able to assume nobody is overwriting its memory isn't borne…

> Except, that sort of thing is important in places like gevent, pytest, and numba

What, mutating the data representation of built-in types documented to be immutable? For what purpose?

Re: Python performance myths and fairy tales

#162

Earlier quoted context omitted.

I love this “real work”. Real work, like writing linked lists, array bounds checking, all the error handling for opening files, etc, etc? There is a reason Python and C both have a use case, and it’s obvious Python will never be as fast as C doing “1 + 1”. The real “real work” is in getting stuff done, not just making sure the least amount of cpu cycles are used to accomplish some web form generation. Anyway, I think…

I believe they are talking about the processor doing real work, not the programmer.

Yeah, I get it, but I found the choice of words funny, because these words can apply in the larger context. It's like saying, Python transfers work from your man hours to cpu hours :)

Re: Python performance myths and fairy tales

#163
post #137

Earlier quoted context omitted.

I love this “real work”. Real work, like writing linked lists, array bounds checking, all the error handling for opening files, etc, etc? There is a reason Python and C both have a use case, and it’s obvious Python will never be as fast as C doing “1 + 1”. The real “real work” is in getting stuff done, not just making sure the least amount of cpu cycles are used to accomplish some web form generation. Anyway, I think…

I can't figure out what your first paragraph is about. The topic under discussion is Python performance. We do not generally try to measure something as fuzzy as "real work" as you seem to be using the term in performance discussions because what even is that. There's a reason my post referenced "lines of code", still a rather fuzzy thing (which I already pointed out in my post), but it gets across the idea that whil…

You claimed churning through Python interpretation is not "real work". You now correctly ask the question: what is "real work"? Why is interpreting Python not real work, if it means I don't have to check for array bounds?

Re: Python performance myths and fairy tales

#164
post #137

Earlier quoted context omitted.

I love this “real work”. Real work, like writing linked lists, array bounds checking, all the error handling for opening files, etc, etc? There is a reason Python and C both have a use case, and it’s obvious Python will never be as fast as C doing “1 + 1”. The real “real work” is in getting stuff done, not just making sure the least amount of cpu cycles are used to accomplish some web form generation. Anyway, I think…

I can't figure out what your first paragraph is about. The topic under discussion is Python performance. We do not generally try to measure something as fuzzy as "real work" as you seem to be using the term in performance discussions because what even is that. There's a reason my post referenced "lines of code", still a rather fuzzy thing (which I already pointed out in my post), but it gets across the idea that whil…

I understand what you're saying. In a way, my comment is actually off-topic to most of your comment. What I was saying in my first paragraph is that the words you use in your context of a language runtime in-effeciency, can be used to describe why these in-effeciences exist, in the context of higher level processes, like business effeciency. I find your choice of words amusing, given the juxtoposition of these contexts, even saying "you pay, pay, pay".

Re: Python performance myths and fairy tales

#165

> His "sad truth" conclusion is that "Python cannot be super-fast" without breaking compatibility. A decent case of Python 4.0? > So, maybe, "a JIT compiler can solve all of your problems"; they can go a long way toward making Python, or any dynamic language, faster, Cuni said. But that leads to "a more subtle problem". He put up a slide with a trilemma triangle: a dynamic language, speed, or a simple implementation.…

Yeah, this is a case of "horses for courses", as you suggest.

I love Python. It's amazing with uv; I just implemented a simple CLI this morning for analyzing data with inline dependencies that's absolutely perfect for what I need and is extremely easy to write, run, and tweak.

Based on previous experience, I would not suggest Python should be used for an API server where performance - latency, throughput - and scalability of requests is a concern. There's lots of other great tools for that. And if you need to write an API server and it's ok not to have super high performance, then yeah Python is great for that, too.

But it's great for what it is. If they do make a Python 4.0 with some breaking changes, I hope they keep the highly interpreted nature such that something like Pydantic continues to work.

Re: Python performance myths and fairy tales

#166
post #62
post #58

Earlier quoted context omitted.

The previous paragraph is > Another "myth" is that Python is slow because it is interpreted; again, there is some truth to that, but interpretation is only a small part of what makes Python slow. He concedes its slow, he's just saying it's not related to how interpreted it is.

I would argue this isn't true. It is a big part of what makes it slow. The fastest interpreted languages are one to two orders of magnitude slower than for example C/C++/Rust. If your language does math 20-100 times slower than C, it isn't fast from a user perspective. Full stop. It might, however, have a "fast interpreter". Remember, the user doesn't care if it is a fast for an interpreted language, they are just tr…

i'll answer your argument with the initial paragraph you quoted:

> A compiler for C/C++/Rust could turn that kind of expression into three operations: load the value of x, multiply it by two, and then store the result. In Python, however, there is a long list of operations that have to be performed, starting with finding the type of p, calling its __getattribute__() method, through unboxing p.x and 2, to finally boxing the result, which requires memory allocation. None of that is dependent on whether Python is interpreted or not, those steps are required based on the language semantics.

Re: Python performance myths and fairy tales

#167
post #134
post #131

Earlier quoted context omitted.

Welp there is Mojo so looks like soon you will not really need to care that much. Prob will get better performance than C too.

I've been hearing promises about "better than C" performance from Python for over 25 years. I remember them on comp.lang.python, back on that Usenet thing most people reading this have only heard about. At this point, you just shouldn't be making that promise. Decent chance that promise is already older than you are. Just let the performance be what it is, and if you need better performance today, be aware that there…

You're probably right, Mojo seems to be more "python-like" than actually source-compatible with python. Bunch of features notably classes are missing.

Re: Python performance myths and fairy tales

#168
post #138
post #32

"Rewrite the hot path in C/C++" is also a landmine because how inefficient the boundary crossing is. so you really need "dispatch as much as possible at once" instead of continuously calling the native code

One use of Python as a "glue language" I've seen that actually avoids the performance problems of those bindings is GNU Radio. That is because its architecture basically uses python as a config language that sets up the computation flow-graph at startup, and then the rest of runtime is entirely in compiled code (generally C++). Obviously that approach isn't applicable to all problems, but it really shaped my opinion…

This. Use python only for control flow, and offload data flow to a library that is better suited for this: written in C, uses packed structs, cache friendly, etc.

if you want multiprocessing, use the multiprocessing library, scatter and gather type computation, etc

Re: Python performance myths and fairy tales

#169
post #62

Earlier quoted context omitted.

I would argue this isn't true. It is a big part of what makes it slow. The fastest interpreted languages are one to two orders of magnitude slower than for example C/C++/Rust. If your language does math 20-100 times slower than C, it isn't fast from a user perspective. Full stop. It might, however, have a "fast interpreter". Remember, the user doesn't care if it is a fast for an interpreted language, they are just tr…

i'll answer your argument with the initial paragraph you quoted: > A compiler for C/C++/Rust could turn that kind of expression into three operations: load the value of x, multiply it by two, and then store the result. In Python, however, there is a long list of operations that have to be performed, starting with finding the type of p, calling its __getattribute__() method, through unboxing p.x and 2, to finally boxi…

Typically a dynamic language JIT handles this by observing what actual types the operation acts on, then hardcoding fast paths for the one type that's actually used (in most cases) or a few different types. When the type is different each time, it has to actually do the lookup each time - but that's very rare.

i.e.

if(a->type != int_type || b->type != int_type) abort_to_interpreter();

result = ((intval*)a)->val + ((intval*)b)->val;

The CPU does have to execute both lines, but it does them in parallel so it's not as bad as you'd expect. Unless you abort to the interpreter, of course.

Re: Python performance myths and fairy tales

#170
post #135
post #124

Earlier quoted context omitted.

To put it another way, I choose Python because of its semantics around dynamic operator definition, duck typing etc. Just because I don’t write the bounds-checking and type-checking and dynamic-dispatch and error-handling code myself, doesn’t make it any less a conscious decision I made by choosing Python. It’s all “real work.”

Type checking and bounds checking aren't "real work" in the sense that, when somebody checks their bank account balance on your website or applies a sound effect to an audio track in their digital audio workstation, they don't think, "Oh good! The computer is going to do some type checking for me now!" Type checking and bounds checking may be good means to an end, but they are not the end, from the point of view of t…

> and the sound effect is only a means to the end of making your music sound less like Daft Punk or something

What do you mean. Daft Punk is not daft punk. Why single them out :)

Post reply on HN