Earlier quoted context omitted.
That makes it so that in absolute terms, Python is not as slow as you might naively expect. But we don't measure programming language performance in absolute terms. We measure them in relative terms, generally against C. And while your Python code is speculating about how this Python object will be unboxed, where its methods are, how to unbox its parameters, what methods will be called on those, etc., compiled code i…
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.
Python performance myths and fairy tales
141–150 of 221 posts
Re: Python performance myths and fairy tales
#142Earlier quoted context omitted.
The 200-100 times slower is a bit cherry picked, but use case does matter. Typically from a user perspective, the initial starting time is either manageable or imperceptible in the cases of long running services, although there are other costs. If you look at examples that make the above claim, they are almost always tiny toy programs where the cost of producing byte/machine code isn't easily amortized. This quote fr…
I'm not so much cherry picking as I am specifically talking compute (not I/O,stdlib) performance. However, when measured for general purpose tasks, that would involve compute and things like I/O, stdlib performance, etc., Python on the whole is typically NOT 20-100x times slower for a given task. Its I/O layer is written in C like many other languages, so the moment you are waiting on I/O you have leveled the playing…
Python isn't evaluated line-by-line, even in micropython, which is about the only common implementation that doesn't work in the same way.
Cython VM will produce an AST of opcodes, and binary operations just end up popping off a stack, or you can hit like pypy.
How efficiently you can keep the pipeline fed is more critical than computation costs.
int a = 5;
int b = 10;
int sum = a + b;
Is compiled to: MOV EAX, 5
MOV EBX, 10
ADD EAX, EBX
MOV [sum_variable]
In the PVM binary operations remove the top of the stack (TOS) and the second top-most stack item (TOS1) from the stack. They perform the operation, and put the result back on the stack.That pop, pop isn't much more expensive on modern CPUs and some C compilers will use a stack depending on many factors. And even in C you have to use structs of arrays etc... depending on the use case. Stalled pipelines and fetching due to the costs is the huge difference.
It is the setup costs, GC, GIL etc... that makes python slower in many cases.
While I am not suggesting it is as slow as python, Java is also byte code, and often it's assumptions and design decisions are even better or at least nearly equal to C in the general case unless you highly optimize.
But the actual equivalent computations are almost identical, optimizations that the compilers make differ.
Re: Python performance myths and fairy tales
#143https://docs.modular.com/mojo/why-mojo/#a-member-of-the-pyth...
Re: Python performance myths and fairy tales
#144> 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.…
Re: Python performance myths and fairy tales
#145"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
In my opinion in most cases where you might want to write a project in two languages with FFI, it's usually better not to and just use one language even if that language isn't optimal. In this case, just write the whole thing in C++ (or Rust).
There are some exceptions but generally FFI is a huge cost and Python doesn't bring enough to the table to justify its use if you are already using C++.
Re: Python performance myths and fairy tales
#146Python as a language will likely never have a "fast" implementation and still be Python. It is way too dynamic to be predictable from the code alone or even an execution stream in a way that allows you to simplify the actual code that will be executed at runtime either through AOC or JIT. The language is itself is also quite large in terms of syntax and built-in capability at this point which makes new feature-conple…
Pypy is 10x faster and is compatible with most cpython code. IMHO it was a big mistake not to adopt JIT during the 2-to-3 transition.
Re: Python performance myths and fairy tales
#147Earlier quoted context omitted.
I guess you mean "N". 10 is a literal, not a name. The part "N cannot be assumed to be ten, because that could be changed elsewhere in the code" implies well enough that the change could be to a non-integer value. (For that matter, writing `N: int = 10` does nothing to fix that.)
No, I mean the literal. CPython is more flexible than it has any right to be, and you're free to edit the memory pointed to by the literal 10.
Re: Python performance myths and fairy tales
#148In the "dynamic" section, it's much worse than the author outlines. You can't even assume that the constant named "10" will point to a value which behaves like you expect the number 10 to behave.
Re: Python performance myths and fairy tales
#149"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
These days it's "rewrite in Rust". Typically Python is just the entry and exit point (with a little bit of massaging), right? And then the overwhelming majority of the business logic is done in Rust/C++/Fortran, no?
That is probably why his demo was Sobel edge detection with Numpy. Sobel can run fast enough at standard resolution on a CPU, but once that huge buffer needs to be read or written outside of your fast language, things will get tricky.
This also comes up in Tauri, since you have to bridge between Rust and JS. I'm not sure if Electron apps have the same problem or not.
Re: Python performance myths and fairy tales
#150Earlier quoted context omitted.
No, I mean the literal. CPython is more flexible than it has any right to be, and you're free to edit the memory pointed to by the literal 10.
Care to show how you believe this can be achieved, from within Python?
import ctypes
ten = 10
addr = id(ten)
class PyLongObject(ctypes.Structure):
_fields_ = [
("ob_refcnt", ctypes.c_ssize_t),
("ob_type", ctypes.c_void_p),
("ob_size", ctypes.c_ssize_t),
("ob_digit", ctypes.c_uint32 * 1),
]
long_obj = PyLongObject.from_address(addr)
long_obj.ob_digit[0] = 3
assert 10 == 3
# using an auxiliary variable to prevent any inlining
# done at the interpreter level before actually querying
# the value of the literal `10`
x = 3
assert 10 * x == 9
assert 10 + x == 6