Ruby keeps on getting better. I wouldn't hesitate to start new projects in ruby.
> I’ve been interested in speeding up allocations for quite some time. We know that calling a C function from Ruby incurs some overhead, and that the overhead depends on the type of parameters we pass.
> it seemed quite natural to use the triple-dot forwarding syntax (...).
> Unfortunately I found that using ... was quite expensive
> This lead me to implement an optimization for ... .
That’s some excellent yak shaving. And speaking up … in any language is good news even if allocation is not faster.
Thank you! Wish it had panned out for Class#new, but I don't feel bad about doing it. :)
Giving new its own instruction makes sense.
Can someone explain, is YJIT being abandoned over the new ZJIT? [0]
And if so, will these YJIT features likes Fast Allocations be brought to ZJIT?
It's not being abandoned, we're just shifting focus to evaluate a new style of compiler. YJIT will still get bug fixes and performance improvements.
ZJIT is a method based JIT (the type of compiler traditionally taught in schools) where YJIT is a lazy basic block versioning (LBBV) compiler. We're using what we learned developing and deploying YJIT to build an even better JIT compiler. IOW we're going to fold some of YJIT's techniques in to ZJIT.
> And if so, will these YJIT features likes Fast Allocations be brought to ZJIT?
It may not have been clear from the post, but this fast allocation strategy is actually implemented in the byte code interpreter. You will get a speedup without using any JIT compiler. We've already ported this fast-path to YJIT and are in the midst of implementing it in ZJIT.
Thanks for all the work you all are putting into Ruby! The improvements in the past few years have been incredible and I'm excited to see the continuous efforts in this area.
But Aaron, what do you actually do here?!
I’m so glad to see your work, and it’s always such a treat to read any of your new posts. Hope to see upcoming ones more often!
Why is a traditional method based JIT better than an LBBV JIT? I thought YJIT is LBBV because it's a better fit for Ruby, whereas traditional method based JIT is more suitable for static languages like Java.
One reason is that we think we can make better use of registers. Since LBBV doesn't "see" all blocks in a particular method all at once, it's much more challenging to optimize register use across basic blocks. We've added type profiling, so ZJIT can "learn" types from the runtime.
Are you piggybacking on LLVM for registerallocation and things like that or building from scracth?
I can imagine combining BBV type branching info with register tracing would add a lot of complicated structures, but I thought the BB's of BBV was more or less analogous to SSA blocks so no middle ground to be found? (consdering if there are many megamorphic sites in the standard library?)
Usual caveat that while Java is mostly static, is has dynamic runtime semantics inherited from Smalltalk and Objective-C, with dynamic class loading, bytecode generation, proxy classes, reflection, hence why the research work on Smalltalk and Strongtalk ended up being so useful for Hotspot.