14 ms·
How many lines of C it takes to execute a + b in Python
- ctenb 3y agoWhat's the answer?
- a3w 3y agoRunning `__radd__(tyepof(b) b)` on `a` seems like a complicated problem. So: Many LoC? Or, the generic, useless but correct, answer: it depends (as the linked article said, too)
- varjag 3y agoIt shoud've been possible to establish the lower and upper bounds.
- baq 3y agoit's about as possible as solving the halting problem if you allow for operator overloading.
- varjag 3y agoLeaving aside the apparent confusion between C and C++, do you really imply overloading could make adding two fixed size numbers in Python take unbounded time?
- baq 3y agoI'm saying a + b in Python can do whatever you override the __add__/__radd__ to. Not sure why you invoke C/C++ here. If you only limit yourself to numbers (the title doesn't specify that) it should be bounded, but the article goes into some depth here, so I'll leave it at that.
- varjag 3y agoFair!
- FartyMcFarter 3y agoBut this has nothing to do with the halting problem. You can run the code, you don't need to do this theoretically.
- FartyMcFarter 3y agoNo. All you need to do is use a code coverage tool to find out which lines are run.
- andromaton 3y agoArticle does not answer the question on its title.
- Karellen 3y agoIt's hard to say. How many lines of code does it take to call typeobj->tp_as_number->nb_add() when `tp_as_number` is a pointer to a `struct float_as_number`, and `nb_add` is a pointer to `float_add`? Do struct definitions count as "lines of code called"?
- andai 3y agoA 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 software is exposed to the web. None of my Python programs are, so assuming all this is true, I'd much prefer to have a "I'm offline, please run twice as fast!" flag (or env variable).
- tyingq 3y agoIt looks like you can disable the slower randomized hashing yourself by setting PYTHONHASHSEED to 0. Though I don't know if there's further speedup to be had by using a different hash implementation. https://docs.python.org/3/using/cmdline.html#envvar-PYTHONHASHSEED https://docs.python.org/3/using/cmdline.html#envvar-PYTHONHA... The original issue: https://bugs.python.org/issue13703 https://bugs.python.org/issue13703
- masklinn 3y agoThat only disables the keying of the hash function (sets the initial value to 0), it does not change the hash function. The hashseed is a per-process value, it has basically no impact on performances.
- deleted 3y ago[deleted]
- a_humean 3y agoI'm aware that Rust has something similiar for things like `std::collections::HashMap`. By default: > The default hashing algorithm is currently SipHash 1-3, though this is subject to change at any point in the future. While its performance is very competitive for medium sized keys, other hashing algorithms will outperform it for small keys such as integers as well as large keys such as long strings, though those algorithms will typically not protect against attacks such as HashDoS. https://doc.rust-lang.org/std/collections/struct.HashMap.html https://doc.rust-lang.org/std/collections/struct.HashMap.htm... However, Rust also lets you pick or implement your own hash algorithm if you want to optimise for your usecase.
- rhabarba 3y agoSounds like it would be easier to just use C anyway.
- benj111 3y agoEasier for whom? The whole point of high level languages is that you put in effort upfront to make everyone elses job easier. By you logic, using machine code directly onto toggle switches is easiest. No assembler to write, no test editor to write.....
- klysm 3y agoEasier is exactly what that wouldn’t be
- globular-toast 3y agoIt's even easier to just buy a desk calculator or even just learn long addition and do it with pencil and paper.
- rhabarba 3y agoActually, I generally recommend to not leave easy tasks to the computer. The brain likes to have to do stuff sometimes.
- llamaInSouth 3y agowhy waste time?
- deleted 3y ago[deleted]
- unnah 3y agoYes, but C is a much more arcane and complicated language. Case in point: instead of writing a+b in Python, in C you would have to write a+b (Jokes aside, it would really be more complicated in C if a and b were actually strings or lists.)
- CardiB 3y ago[flagged]
- Dwedit 3y agoLines of C aren't the defining factor. You want total instructions executed.
- flohofwoe 3y agoIME I'd say a line of typical C code (not necessarily C++ code) maps to around 1..5 instructions on average. It's still a quite useful measure to get a rough idea how much CPU work happens.
- jasode 3y ago>Lines of C aren't the defining factor. You want total instructions executed. I understand what your clarification is trying to provide but it isn't relevant to this particular thread's article. The article is not about "performance benchmarks" where you need cpu instructions as a definitive unit-of-measure for comparisons. Instead of measuring performance, the author's theme in this case is more akin to "decompiling" or "reverse-engineering". He takes a tiny piece of Python code and then maps it back to the actual CPython source *.c and *.h files that implements the Python vm. He added several deep links to the relevant sections of CPython source code on Github to help illustrate the mappings between Python's BINARY_OP to the .c and .h files. The article is sharing the type of knowledge you'd gain by loading up CPython in a debugger and single-stepping through the source code line-by-line. In other words, the article's title could also have been: "Which Lines of CPython does it Take to Execute a + b in Python?" For the scope of this particular article, the "lines of C" _are_ the defining factor because the subject of dissection is CPython's .c/.h files.
- bufo 3y agoIt’s about 100 for x86_64 https://www.computerenhance.com/p/waste https://www.computerenhance.com/p/waste
- mobiuscog 3y agoThere was some high-level discussion of this in the chat Guido van Rossum had with Lex Fridman (timestamped): https://youtu.be/-DVyjdw4t9I?t=3964 https://youtu.be/-DVyjdw4t9I?t=3964
- Uptrenda 3y agoPython's math operations are going to need a lot of C code because the numbers can be any size. It's part of what makes it so great for scientific computing (as you don't have to spend hours implementing arbitrary precision math - probably badly.) If that's too slow though there's always NumPy.
- KeplerBoy 3y agoThat's only true for integers. For scientific applications you'd typically want floating points and Python's floats are just regular ieee-754 doubles (or whatever "double" meant to the compiler used to compile that python interpreter).
- yeshman 3y agoPython also has a fixed point arithmetic in its std library: https://docs.python.org/3/library/decimal.html https://docs.python.org/3/library/decimal.html
- Uptrenda 3y agoThe disadvantage with floats is you can't do accurate computations due to having an inexact representation. Python has the same issues with floats. For example: I do a lot of work with financial software and also some basic applied cryptography. And the essential rule is to never ever use floats. Where 'decimals' are needed you want them to be simulated using integers. Python has a module called decimal which I think helps mitigate some of these issues. I've written some code to work with accurate, large precision numbers in Python and C before. Mostly the annoying part with this is having data types for the numbers that correspond well to database fields (like uint64) or are portable (in C its easiest if you can get a u128 but this type is very compiler-specific so some hacking may be needed.) It's fun to work on code like this but definitely needs to be precise and have good test coverage. Writing your own math libraries that are going to be used for such important operations is hair-raising stuff.
- cozzyd 3y agoIf only there were libraries for multiprecison arithmetic in other languages...
- mgl 3y agoA more thorough comparison of time, energy and memory required to execute similar Python, C, Rust, Java, C#, etc. code: https://stratoflow.com/efficient-and-environment-friendly-programming-languages/#energy https://stratoflow.com/efficient-and-environment-friendly-pr... And why Mojo could be an answer for high (well, higher) performance Python: https://stratoflow.com/introduction-to-mojo-programming-language/ https://stratoflow.com/introduction-to-mojo-programming-lang...
- geertj 3y agoThe Python C API has become so verbose that I recommend against using it directly. Recently I mapped a few external libraries using Nanobind, and the result was significantly more concise. Nanobind uses the type system of modern C++ (17 and above) to provide most argument conversions, Mapping C functions is typically just a few lines of code. It also provides a great way to map C++ constructs such as classes, exceptions, and standard containers. Nanobind is by the same author that started pybind11, used by Tensorflow and PyTorch. The web site [1] contains a bit more of the rationale. [1] https://nanobind.readthedocs.io/en/latest/why.html https://nanobind.readthedocs.io/en/latest/why.html
- BD103 3y agoThis was quite interesting, but I’m disappointed it didn’t mention how many lines in C it actually took to run. Perhaps a profiler might help calculate this?
- whizzter 3y agoIf you read the article you can see that some codepaths can invoke Malloc with all the follow-on effects like Kernel boundary crossings that this implies, it's thus quite random.
- serial_dev 3y agoIt would still make sense to give a number or a range.
- whizzter 3y agoDepends, I look at it from a performance standpoint when starting to count lines/instructions, not just directly executed code but also how feasible it would be to translate the thing to a JIT for example, the amount is large enough that going to a JIT would yield little (this is why there has been so many Python JIT's that has failed to gain enough performance and hence traction) before mayor architectural fixes are made. Not only is there branches to a ton of special things but also macros that hides even more lines (IncRef/DecRef probably has a lot of magic behind there).
- serial_dev 3y agoPerformance is not the only important metric, and LoC is a good approximation to B complexity.
- layer8 3y agoSince malloc() is a standard C library function, it would be okay to not count its implementation (which isn’t necessarily written in C).
- vitiral 3y agoIt seems like it doesn't answer it's own question, so I'll pose another. The entire Lua core is 15kLoC. Is that more than or less than what's needed for python's "a + b", assuming a and b are defined. I'm genuinely curious.
- kevindamm 3y agoYes, it's a very tootsie-roll-center kind of answer, but it's clearly more than a few. To answer your question, 15kLoC is more than enough to implement dynamic dispatch and the PyObject base struct, along with the special method logic for __add__ on any python object type.. but still a lot less than what's needed for all the special method types and a lot of boilerplate for the C-compatible interface around those methods.
- demondemidi 3y agoI wonder what percent of this audience got the tootsie-roll reference. Does anyone under 40 know it?
- steveklabnik 3y agoI am about to turn 38 and I got it, so it's at least slightly lower than 40.
- deleted 3y ago[deleted]
- vitiral 3y agoHey Steve, loved your work on Rust and your goodbye letter. Nice to see you in my comment chain
- steveklabnik 3y agoThanks!
- 3y ago
- toxik 3y ago[flagged]
- frankfrank13 3y agoIsn't that just the Substack default? so much better than Medium's or others, at least it closes. Besides, Substack is one of the more writer-friendly platforms re: take-home-pay and no ads, so maybe reconsider?
- Retr0id 3y agoWriter-friendliness doesn't need to be at odds with reader-friendliness.
- spenczar5 3y agoSometimes it seems like they do need to be opposed. For the writer to get paid, the reader needs to be asked to pay, or exploited quietly. I don’t know a way out :(
- another-dave 3y agoIt's not about what, it's about when though — like the GP, I got a pop-up fairly immediately before I'd engaged in the article so I just closed the tab. The best time to engage me is after I've enjoyed the article and hopefully interested to hear more from the writer rather than immediately landing on the page. It's the equivalent to sales staff jumping on customers in shops the minute they walk in the door — "can I help you with anything today?" — before you even have a chance to see what the shop is like.
- davidivadavid 3y ago"I would rather not read this article than have to click a button" is an interesting level of entitlement. Hope you never had your fingers stained by the ink when reading the newspaper, you probably would have sued the New York Times.
- deleted 3y ago[deleted]
- KolenCh 3y agoI have a real life example in this commit: https://github.com/hpc4cmb/toast/pull/380/commits/a38d1d6dbcc97001a1ad1c315bb08cf1eecc74c7 https://github.com/hpc4cmb/toast/pull/380/commits/a38d1d6dbc... Replacing 2 lines of python code (with tens of glue code in Numba) with hundreds lines of C++ with glue code.
- deleted 3y ago[deleted]
- fweimer 3y agoThe general topic is covered in Brett Cannon's “Python is (mostly) made of syntactic sugar” series of posts, via translation of high-level semantics into a subset of Python. LWN has a high-level summary: https://lwn.net/Articles/942767/ https://lwn.net/Articles/942767/ The actual posts are here: https://snarky.ca/tag/syntactic-sugar/ https://snarky.ca/tag/syntactic-sugar/ (multiple pages!)
- pphysch 3y agoWe know that addition is a relatively trivial operation, say, on 64 bit integers. A more interesting example IMO would be something like "how many lines of C it takes to execute person.name='Bob' in Python, where person.name is undefined". That would better demonstrate why we use Python in the first place (hint: it's not "to add integers"), while also indicating why it is slow.
- sroussey 3y agoYou would be shocked at how bad/slow addition is in a CPU/GPU or any digital ALU.
- neillyons 3y agoThere is a really good ten hour walkthrough of Python 2 internals https://youtube.com/playlist?list=PLzV58Zm8FuBL6OAv1Yu6AwXZrnsFbbR0S&si=YKlbjy0CxM7VPaJq https://youtube.com/playlist?list=PLzV58Zm8FuBL6OAv1Yu6AwXZr...
- mediumsmart 3y agoI can’t find the number of lines it takes in the article. Is it mentioned there?