Earlier quoted context omitted.
Some languages are much harder to compile well to machine code. Some big factors (for any languages) are things like: lack of static types and high "type uncertainty", other dynamic language features, established inefficient extension interfaces that have to be maintained, unusual threading models...
The simplest JIT just generates the machine code instructions that the interpreter loop would execute anyway. It’s not an extremely difficult thing, but it also doesn’t give you much benefit. A worthwhile JIT is a fully optimizing compiler, and that is the hard part. Language semantics are much less important - dynamic languages aren’t particularly harder here, but the performance roof is obviously just much lower.
Python 3.15's JIT is now back on track
301–310 of 330 posts
Re: Python 3.15's JIT is now back on track
#302Earlier quoted context omitted.
To clarify, it is nuts that in an object method, there is a performance enhancement through caching a member value. class SomeClass def init(self) self.x = 0 def SomeMethod(self) q = self.x ## do stuff with q, because otherwise you're dereferencing self.x all the damn time
> it is nuts that in an object method, there is a performance enhancement through caching a member value i don't understand what you think is nuts about this. it's an interpreted language and the word `self` is not special in any way (it's just convention - you can call the first param to a method anything you want). so there's no way for the interpreter/compiler/runtime to know you're accessing a field of the class…
A common approach is hidden classes that work much like classes in other languages. Reading a simple int property just reads bytes at an offset from the object pointer directly. Upon entry to the method bits of the object are tested and if the object is not known to be simple it escapes into the full dynamic machinery.
I don't know if those exact techniques would work for Python but this is not an either-or situation.
See also: modern Objective-C msg_Send which is so fast on modern hardware for the fast-path it is rarely a performance bottleneck. Despite being able to add dynamic subclasses or message forward at runtime.
Re: Python 3.15's JIT is now back on track
#303Earlier quoted context omitted.
Another thread can access it and do that, how could the compiler possibly know about it?
There are documented ways to ensure that changes are visible across threads (e.g. locks). If these are not used, the compiler is within its rights to not go out of its way to pull changes from another thread.
Re: Python 3.15's JIT is now back on track
#304[flagged]
Jumping 12 major versions to one that doesn't exist yet must yield quite the performance boost.
$ time python3.15 -c "while True: print('hello world')"
bash: python3.15: command not found
real 0m0.005s
user 0m0.000s
sys 0m0.002sRe: Python 3.15's JIT is now back on track
#305Earlier quoted context omitted.
But now you are no longer talking about the way Python works, but the way you want Python to work - and that has nothing to do with Python.
"The way our economy works is bad" "That's how it's been since forever, it's an essential part of country X" "Yes, and it's a badly designed part". "But now you are no longer talking about the way country X works, but the way you want country X to work - and that has nothing to do with country X." See how the argument quickly degenerates?
Re: Python 3.15's JIT is now back on track
#306Earlier quoted context omitted.
There are documented ways to ensure that changes are visible across threads (e.g. locks). If these are not used, the compiler is within its rights to not go out of its way to pull changes from another thread.
Except python has a well documented global lock.
Re: Python 3.15's JIT is now back on track
#307Earlier quoted context omitted.
In Python attribute access aren't stable! `self.x` where `x` is a property is not guaranteed to refer to the same thing. And getting rid of descriptors would be a _fundamental change to the language_. An immeense one. Loads of features are built off of descriptors or descriptor-like things. And what you're complaining about is also not true in Javascript world either... I believe you can build descriptor-like things…
>Remember, this is a scripting language, not a compiled language This is the fundamental issue and "elephant in the room" that everyone is seems to be overlooking, and putting under the carpet. The extreme compiled type language guys going gung-ho with very slow to compile and complicated Rust (moreso than C++), while the rest of the world gladly hacking their shiny ML/AI codes in scripting language aka Python "the g…
I regret to inform you that there are _loads_ of multi-decades-old Python stacks at this point.
On the micro level I'll be like "ugh wish I wasn't paying the costs of Python" decently enough. But on the macro level I don't regret Python stacks. At least not when looking at the alternatives.
Tho I will admit I'm a bit mystified at data science stuff in particular persisting in Python. Lots of CPU churn even if the underlying libs are all C extensions.
Re: Python 3.15's JIT is now back on track
#308Earlier quoted context omitted.
The simplest JIT just generates the machine code instructions that the interpreter loop would execute anyway. It’s not an extremely difficult thing, but it also doesn’t give you much benefit. A worthwhile JIT is a fully optimizing compiler, and that is the hard part. Language semantics are much less important - dynamic languages aren’t particularly harder here, but the performance roof is obviously just much lower.
Agree re: different types of JITs producing wildly different results but don't agree about language semantics - even a Java JIT has to give up speed due to certain seemingly minor language and JVM issues. So both matter - no matter how good of a compiler engineer you are, some semantics are just not optimizable. Indeed, the use of a "trace JITs" is a proof of that.
It’s very much possible to make something less advanced than JVM or CLR, or even V8, that will still outperform an interpreter, even for an extremely dynamic language like Python.
As others have mentioned, the roadblock here is that interpreter internals are too public, so doing it without breaking the C API that extensions use is really hard.
Re: Python 3.15's JIT is now back on track
#309Earlier quoted context omitted.
Where is the major win? Sorry but I just don't see the use case for free-threading. Native code can already be multi-threaded so if you are using Python to drive parallelized native code, there's no win there. If your Python code is the bottleneck, well then you could have subinterpreters with shared buffers and locks. If you really need to have shared objects, do you actually need to mutate them from multiple interp…
> Native code can already be multi-threaded so if you are using Python to drive parallelized native code, there's no win there. When using something like boost::python or pybind11 to expose your native API in Python, it is not uncommon to have situations where the native API is extensible via inheritance or callbacks (which are easy to represent in these binding tools). Today with the GIL you are effectively forced t…
Bigger thing imo is that multiprocessing is just really annoying. In/out has to be pickleable, anything global gets rerun in each worker which often requires code restructuring, it doesn't work with certain frameworks, and other weird stuff happens with it.