Live data from Hacker News

How many lines of C it takes to execute a + b in Python

codeconfessions.substack.com

131–140 of 224 posts

Re: How many lines of C it takes to execute a + b in Python

#131

Earlier quoted context omitted.

This may be a somewhat uninformed opinion, but I think CPython is just straight up not particularly good software. There are a million and one optimizations that other major scripting runtimes (V8, LuaJIT, PyPy, Ruby YJit etc.) have had for years that CPython is lacking. This is by design though. CPython has never been focused on performance, that's why it's not even JIT. It optimizes for simplicity and easy interope…

It's great software for the use case that Python is intended for . Python is supposed to be glue code. You embed a scripting runtime in your application, do all the heavy lifting in C, but configure your building blocks in Python so that you can easily reconfigure them as needs change. NumPy, SciPy, TensorFlow, PyTorch, JAX, Pandas, Pillow, lxml, cjson, PyCapnP, Tornado, fast-avro, etc. all get it right. They are wra…

Arguably no one’s goal is to glue pieces of C together. That’s too abstract. Their goal is to do something like write a performant web server, maybe easily and quickly. Python’s approach is one way to do that, but there are other ways that might be better. Having to write code in two languages to solve a problem, one of which that is difficult to write and has lots of footguns, has some clear downsides.

Re: How many lines of C it takes to execute a + b in Python

#132
post #122

Earlier quoted context omitted.

Unfortunately Python's innard is much more complicated than most expectations. You have named JS and Lua, but those languages never have "magic" methods---JS instead has prototypes and more recently proxies, while Lua has metatables. Ordinary objects aren't magic in this sense, and conversely magical objects are generally deliberate choices in those languages. But Python's magic `__dunder__` methods are everywhere in…

In the late 1990s and early 200xs, there were a lot of claims that there was no such thing as a "slow language", that all languages can be run as quickly as C if you just built a sufficiently smart compiler and/or runtime. I haven't heard anyone make this claim in a while. The inability to speed up Python beyond a certain point despite a lot of clever approaches taken was probably a good chunk of the reason, the rema…

"Tech debt doesn't matter!"

"We're going to redesign it the right way after we get this version out the door!"

Re: How many lines of C it takes to execute a + b in Python

#133
post #4

A while back someone posted their patch to cpython where they replaced the hash function with a fast one and claimed this dramatically sped up the whole Python runtime. They claimed that the hash function was used constantly —e.g. 11 times in print("hello world")—because it's used to look up object properties. Apparently the default implementation is not optimized for performance but for security, just in case the so…

This may be a somewhat uninformed opinion, but I think CPython is just straight up not particularly good software. There are a million and one optimizations that other major scripting runtimes (V8, LuaJIT, PyPy, Ruby YJit etc.) have had for years that CPython is lacking. This is by design though. CPython has never been focused on performance, that's why it's not even JIT. It optimizes for simplicity and easy interope…

Just yesterday I compared the small language I created to Python. Was surprised my tree walking interpreter somehow beat Python's bytecode virtual machine at recursive Fibonacci. It was just a simple hyperfine benchmark so I might be confounding code execution performance with the initialization time. Still caught me totally off guard and gave me a huge confidence and motivation boost. I was thinking something like "OK let's see just how bad this thing is" but it actually beat Python at something.

Re: How many lines of C it takes to execute a + b in Python

#134
post #131

Earlier quoted context omitted.

It's great software for the use case that Python is intended for . Python is supposed to be glue code. You embed a scripting runtime in your application, do all the heavy lifting in C, but configure your building blocks in Python so that you can easily reconfigure them as needs change. NumPy, SciPy, TensorFlow, PyTorch, JAX, Pandas, Pillow, lxml, cjson, PyCapnP, Tornado, fast-avro, etc. all get it right. They are wra…

Arguably no one’s goal is to glue pieces of C together. That’s too abstract. Their goal is to do something like write a performant web server, maybe easily and quickly. Python’s approach is one way to do that, but there are other ways that might be better. Having to write code in two languages to solve a problem, one of which that is difficult to write and has lots of footguns, has some clear downsides.

Ritchie and Thompson might disagree with you.

Re: How many lines of C it takes to execute a + b in Python

#135
post #4

A while back someone posted their patch to cpython where they replaced the hash function with a fast one and claimed this dramatically sped up the whole Python runtime. They claimed that the hash function was used constantly —e.g. 11 times in print("hello world")—because it's used to look up object properties. Apparently the default implementation is not optimized for performance but for security, just in case the so…

Hash function security is certainly a concern due to hash flooding attacks which force worst case performance hash table lookup and leads to denial of service.

https://peps.python.org/pep-0456/

Re: How many lines of C it takes to execute a + b in Python

#136
post #122

Earlier quoted context omitted.

Unfortunately Python's innard is much more complicated than most expectations. You have named JS and Lua, but those languages never have "magic" methods---JS instead has prototypes and more recently proxies, while Lua has metatables. Ordinary objects aren't magic in this sense, and conversely magical objects are generally deliberate choices in those languages. But Python's magic `__dunder__` methods are everywhere in…

In the late 1990s and early 200xs, there were a lot of claims that there was no such thing as a "slow language", that all languages can be run as quickly as C if you just built a sufficiently smart compiler and/or runtime. I haven't heard anyone make this claim in a while. The inability to speed up Python beyond a certain point despite a lot of clever approaches taken was probably a good chunk of the reason, the rema…

Can someone explain what exactly it is about Python's design that makes it slow?

What changes would have to be made to speed it up? Obviously changing its core design now would break things, but my question is, can we can imagine an alternate universe Python that's as close as possible to our Python, except really fast? What would be different?

Re: How many lines of C it takes to execute a + b in Python

#137
post #122

Earlier quoted context omitted.

Unfortunately Python's innard is much more complicated than most expectations. You have named JS and Lua, but those languages never have "magic" methods---JS instead has prototypes and more recently proxies, while Lua has metatables. Ordinary objects aren't magic in this sense, and conversely magical objects are generally deliberate choices in those languages. But Python's magic `__dunder__` methods are everywhere in…

In the late 1990s and early 200xs, there were a lot of claims that there was no such thing as a "slow language", that all languages can be run as quickly as C if you just built a sufficiently smart compiler and/or runtime. I haven't heard anyone make this claim in a while. The inability to speed up Python beyond a certain point despite a lot of clever approaches taken was probably a good chunk of the reason, the rema…

You could add in continuation support as well as unbounded stack size to make it even more difficult to implement efficiently. There are tricks these days for implementing continuations somewhat efficiently (and by somewhat, I mean that they're only 3-5x slower than explicit continuation passing with lambdas), but these tricks largely don't work in WASM without doing something extreme like completely ignoring the WASM stack and storing return addresses/current continuation on the WASM heap.

Unbounded stack size is similarly difficult for WASM because like before, you have to be very careful about using the WASM stack.

Even with C++, you basically need to drop down to intrinsics or assembly to make full use of SIMD.

Re: How many lines of C it takes to execute a + b in Python

#138
post #110

Earlier quoted context omitted.

I don't disagree with you but, now you can retrofit a JIT into python. https://blog.pyston.org/2022/09/29/announcing-3-7-3-10-suppo...

"We think of the breakdown roughly as follows: of our roughly 30% original speedup, 10% is going into Pyston-lite, 10% was done independently by the CPython team between 3.8 and main, and the remaining 10% we are hoping to contribute back upstream." To compare with Javascript: if I remember, as it appeared, V8 JIT was orders of magnitude faster, compared to the interpreted code.

There was also a bunch of effort being put into efficiency of JavaScript. But now the tables have been changed and Microsoft is putting a large amount of effort into Python .

Re: How many lines of C it takes to execute a + b in Python

#139
post #113

Earlier quoted context omitted.

In my eyes, "good software" does not necessarily just mean something that accomplishes its goals. You can set a goal of being bad, and that's kind of what CPython is doing. Of course, "good" and "bad" are relative. If you don't care about performance then there's nothing wrong with CPython.

I agree with that estimate, I think it was really the idea of Python to be less than "good" by design. I mean one doesn't need more than: >>> exit Use exit() or Ctrl-D (i.e. EOF) to exit to see. They have that special handling, but they still don't want to let you out, because... IMO, they just want to be annoying. When a solution could be something like: Note: exit() is needed in scripts. In this prompt Ctrl-D (i.e.…

I think this is to be consistent that exit is not a statement but a function. This was done with print. 3.0 was an ergonomic fix for cpython developers and language consistency fixes (also redoing the Unicode implementation).

Re: How many lines of C it takes to execute a + b in Python

#140
post #131

Earlier quoted context omitted.

It's great software for the use case that Python is intended for . Python is supposed to be glue code. You embed a scripting runtime in your application, do all the heavy lifting in C, but configure your building blocks in Python so that you can easily reconfigure them as needs change. NumPy, SciPy, TensorFlow, PyTorch, JAX, Pandas, Pillow, lxml, cjson, PyCapnP, Tornado, fast-avro, etc. all get it right. They are wra…

Arguably no one’s goal is to glue pieces of C together. That’s too abstract. Their goal is to do something like write a performant web server, maybe easily and quickly. Python’s approach is one way to do that, but there are other ways that might be better. Having to write code in two languages to solve a problem, one of which that is difficult to write and has lots of footguns, has some clear downsides.

Gluing pieces of C together was literally the reason I started using Python back in the 1990s.

My other two main options were Tcl and Perl. Tcl was excellent at gluing, but worse at scaling, with no namespaces (then) and OO only as third-party add-ons.

Perl extensions were not so easy (better with Perl 5), and much as I enjoyed the language, handling complex data structures, was not for the faint-hearted.

Gluing pieces of C together is why we have NumPy, PyQt, pywin32, wxPython, and tens of thousands of other packages that work with C/C++/Fortran libraries.

Post reply on HN