12 ms·
RJIT, a new JIT for Ruby
- yxhuvud 4y agoAre they adding a new jit each version now?
- pmarin 4y agoIt is replacing MjIT by the same author.
- pawelduda 4y agoQuite interesting. My takeaway is that it can be on par with YJIT or even outperform it despite being in early development. Btw one project I work on switched to YJIT in production and there are no problems so far (but no noticeable perf gains either)
- weatherlight 4y agoWhat about in memory usage?
- stanislavb 4y agoYeah, I have the same experience with SaaSHub. I moved to YJIY a week ago - no issues, but no noticeable perf gains either (unfortunately).
- maxime_cb 4y agoYou're right that the peak performance could be on par (or even better), but, and I acknowledge that I'm biased since I'm tech lead of the YJIT team, my takeaway is: 1. Kokubun, who works with us on the YJIT team, is leveraging insights he's learned while working on YJIT to build this. He has said so in his tweets, some of the code in RJIT is a direct port of the YJIT's code to Ruby. This is his side-project. 2. One of the challenges we face in YJIT is memory overhead. It's something we've been working hard to minimize. Programming RJIT in Ruby is going to make this problems worse. Not only will it be hard to be more memory-efficient, you're going to increase the workload of the Ruby GC (which is also working to GC your app's data). 3. Warm-up time will also be worse due to Ruby's performance not being on par with Rust. This doesn't matter much for smaller benchmarks, but for anything resembling a production deployment, it will. On your second point, if you're not seeing perf gains with YJIT, we'd be curious to see a profile of your application, and the output of running with `--yjit-stats`. You can file an issue here to give us your feedback, and help us make YJIT better: https://github.com/Shopify/yjit/issues https://github.com/Shopify/yjit/issues
- akanet 4y agoMaxime, just wanna say I'm a big fan of your work https://twitter.com/fulligin/status/1524652417559646208 https://twitter.com/fulligin/status/1524652417559646208
- cztomsik 4y ago> Programming RJIT in Ruby is going to make this problems worse. Not only will it be hard to be more memory-efficient, you're going to increase the workload of the Ruby GC Or it could be a win. Java went that way too.
- rco8786 4y agoWhy would one use this over YJIT?
- sparker72678 4y agoRight now maybe you wouldn't, very much (though you should profile your code to see which performs better). But having a JIT written in Ruby potentially makes further development on it more accessible to the community. We will see!
- weatherlight 4y agoseems strange, since most rubyist aren't compiler engineers. I feel like you'd still want to keep writing your compiler in Rust, and try to eek out your performance there. I'm still scratching my head, other than accessibility, Why Ruby over Rust. Note: I'm a Ruby dev, I don't know Rust. I've written few toy interpreters in Elixir and OCaml. This is my very limited understanding of compiler design, etc.
- sparker72678 4y agoI think you could say yjit fills that role; in any case, having multiple active jit projects leaves open a lot of room for experimentation. In the end, you might be right and rjit will fade away — we will see!
- simlevesque 4y ago> most rubyist aren't compiler engineers. You could say that about any language.
- weatherlight 4y agoCan you say that about Standard ML? theres traditionally certain langs with particular ergonomics that lend them self to this kinda work. Like having (parser, lexer libs as apart of the lang's stdlib) Rust's ADT seem particularly useful in this context. it really makes refactoring a breeze. (OCaml has a similar type system.) Your point is generally true though.
- sparker72678 4y agoI love all the attention Ruby performance is getting lately!
- Qem 4y agoCongrats to the Ruby developers, now they are on the way to have more than one production-grade JIT available in the reference implementation. I hope Python catches up soon, and the proposal to merge CPython and Pyston goes forward.
- jhoechtl 4y agoBoy I lost track of all the Ruby Jit attempts. According to the computer language shootout all micro-optimizations
- ezekg 4y agoYJIT sped up my Rails app by about 30%. It has a memory overhead, but it's worth it.
- nerpderp82 4y agoThat is huge, did it also reduce(~~bring in~~) tail latency? *edit, fix confusing vernacular
- ezekg 4y agoNope -- P99 also decreased. I've heard similar things for other Rails apps as well.
- nerpderp82 4y agoSorry, in my usage "bring in" means move tail latency P99/P100 more to the left not as introduce, I'll be more clear next time. So yes! That is great news.
- maxime_cb 4y agoFor anyone curious, we've been working to reduce the memory overhead and have added some stats to keep track of memory usage over time. On this graph, you can see a comparison with the CRuby interpreter: https://speed.yjit.org/memory_timeline#railsbench https://speed.yjit.org/memory_timeline#railsbench
- greenpeas 4y agoWhat happened on jun 14? (the dramatic drop in memory usage) Edit: I guess this (https://github.com/ruby/ruby/pull/5944 https://github.com/ruby/ruby/pull/5944) PR was merged.
- CyberDildonics 4y agoThese comparisons seem to be to other ruby implementations. How does this compare to LuaJIT ?
- brokencode 4y agoThat is kind of irrelevant if you are running a Ruby application. And I think that if a developer is looking to start working on a new web server where performance is a significant concern, they are more likely to look at Go, Rust, or even JavaScript rather than either Lua or Ruby.
- CyberDildonics 4y agoLuaJIT should be much faster than javascript Also how slow is still ok? People can talk about things that aren't 'performance sensitive' but at some point it's going to matter. If a program is serving up web pages, that's an interactive application and people are waiting on the program.
- winrid 4y agoEven a slow framework is still fast for humans. My Django site renders the homepage in 10ms, and django is kind of in the realm of Rails performance wise. It's all about cost, really. But you can just tell Nginx to cache pages and then it's not a problem for the vast majority of use cases.
- sambostock 4y agoSeveral points discussed in these comments are addressed by the author in the linked https://bugs.ruby-lang.org/issues/19420 https://bugs.ruby-lang.org/issues/19420
- mabbo 4y agoDoes RJIT get JIT compiled... by itself? That would be lovely in the sense that as RJIT finds more optimizations to speed up code, it would become itself faster.
- extrememacaroni 4y agoHow many levels of JIT would be too many I wonder
- ignoramous 4y agoAOT + JIT + PGO (profile guided optimization) is where things are at.
- aardvark179 4y agoI mean, that's what happens with JITs like Graal. It can present a warmup issue which is part of the reason Graal did so much work to enable AOT compilation.
- l_theanine 4y agoI'd definitely be more apt to have this as part of production system instead of the Rust one. Rust has got to be the ugliest, most unfriendly programming language I've ever laid my eyes on. And I wrote Perl for 10+ years, so that's really quite a feat of aesthetics failure. Anyhow, I'm pretty impressed with the performance thus far, I like the idea of having multiple JITs available for a single-language ecosystem, regardless of how disgusting the language used to implement them. I think having competition means that there will be a race to the bottom and towards the "center" of general work. It's already really cool to see how the different approaches have clear preferences of the tasks they excel at and where they fall short. This is hugely valuable because it pushes Ruby forward for everybody, and will hopefully result in not only a faster Ruby for X, but a faster Ruby for everything, which is just an objectively good thing. Python is in a weird spot in this arena, because it is very clearly and very strongly orienting itself to continue to dominate practical data science work, and that means the need for JITs to handle regular jobs like text munging and whatnot fall by the side in order for the latest NumPy and Jax stuff, whatever is the current hot shit in the AIverse. Ruby doesn't suffer from that because it's pretty solidly lodged in the web development sphere, while also having a capable presence in netsec tools, application scripting, and probably a few more areas that I'm not aware of. If you're interested in some of cutting edge Python stuff, I'd recommend taking a look at exaloop/Codon. Codon will soon be able to output Python extensions that are compatible with Python's setuptools, so it will soon be possible to just include some .codon files with your project, use setup.py, and have decorators that can (literally) 100x your hot loops.
- bluedays 4y agoBe honest, you mostly write this post so you can say you hate Rust, didn't you?
- l_theanine 4y ago[flagged]
- mdavidn 4y ago> Rust has got to be the ugliest, most unfriendly programming language I've ever laid my eyes on. No, that would be C++ or PHP. I've written Ruby for 10 years. I can't wait for a future in which my team never needs to worry about mutated shared state. Rust is beautiful in this regard. The only languages that come close are Clojure and Haskell, but Rust accomplishes this without immutability or a bloated runtime.
- barrenko 4y agoIs there any alternative to RubyMine as an IDE for Ruby newbies?
- nirvdrum 4y agoFor IDEs, Shopify provides the Ruby Extension Pack for VS Code [1]. Closely related to RubyMine is the Ruby plugin for IntelliJ IDEA. Those seem to be the biggest set of IDEs for several languages. There's Ruby support for editors like Vim and emacs, but that's a different experience from an IDE. [1] -- https://github.com/Shopify/vscode-shopify-ruby https://github.com/Shopify/vscode-shopify-ruby
- Alifatisk 4y agoVscode + solargraph + ruby extension
- pritambaral 4y agoFor those who can Emacs, robe and inf-ruby provide the best developer experience. Robe runs inside a Ruby process, like Common Lisp's SLIME. This is (far) superior to typical IDEs because it's no longer restricted to static analysis. In a highly dynamic language like Ruby, static analysis can do only so much, so RubyMine and LSP servers have to guess data types. Robe doesn't have to. Inf-ruby allows interactive evaluation of code, even including redefinition of methods & classes. The items being redefined don't have to be at the top-level, since inf-ruby automatically extracts the surrounding method and class definitions. This means you can just open any source file of your program, edit any method/class that may or may not be deep inside layers of modules & classes, and just ask inf-ruby to send the edited definition to the running Ruby process. Instant code reload. Of course, it's still Emacs, so sharp corners and rough edges abound. But when it works, it's a boon.
- barrenko 4y agoYe, I noticed trouble with Ruby, RubyMine is the only thing that "works" i.e. provides what I've come to expect out of an IDE for language. Similar experiences for me were Emacs and Clojure or Scala and neovim. Ill try the Emacs setup.
- beders 4y agoIs jRuby still a thing? I didn't see it in the perf comparisons.
- Lio 4y agoYes it’s definitely still a thing. They actually had a new release at the beginning of March. https://www.jruby.org/2023/03/08/jruby-9-4-2-0.html https://www.jruby.org/2023/03/08/jruby-9-4-2-0.html
- mike_hearn 4y agoNeither JRuby nor TruffleRuby are compared to, and both are quite fast especially TruffleRuby.
- zac23or 4y agoI work everyday with Rails. In my experience, Ruby is not super slow. In my machine, I can create 1M of empty hashs on 0.17sec. Benchmark.measure{1000000.times{Hash.new}} @total = 0.1706789999999998s It's very good for a dynamic language. But ActiveRecord (and Rails) are incredibly slow. In my machine in 0.17sec only 2000 Models can be created. Benchmark.measure{2000.times{User.new}} @total = @total=0.17733399999999833. Some SQL+Network runs in less than 10ms, in these cases Active Models creation is slower than that. Yes, Rails can be slower than database access.
- Alifatisk 4y agoI think the idea of Ruby being slow was back in 1.9, this was way before Matz announced the goal of 3x3 with Ruby 3.
- jeltz 4y agoNo, it is actually from even before that, from Ruby 1.8 which did not have a proper VM.
- brigandish 4y agoI think the idea comes from many other mainstream languages being relatively much faster. The classic rejoinder was about expressiveness and developer time, but with newer languages that have learnt from Ruby and others (most obviously Elixir and Crystal, but any of the newer generation could probably be chosen) that's less of an argument. Now it relies on the legacy of Rails more than anything, which isn't so bad, is it? I wouldn't pick it for a new project though if I could write Rust or Elixir or Crystal etc unless they lack something in their ecosystem that Rails has, but over time this will become less of a difference.
- Someone 4y agoI would guess Hash.new does little more than one or two allocations (one for the object, possibly one for an empty hash table that can later be resized), and if it did two allocations, linked one to the other. If so, that probably is more a benchmark of your memory allocator, which probably is written in C than of ruby. I also guess you ran the benchmark from a new ruby instance. That means memory wasn’t fragmented. That certainly doesn’t make the allocator’s job more difficult.
- titzer 4y agoHonest question, I do not know Ruby's semantics well. But, as someone who has worked on many JITs in the past, how is it in these results, three different JITs failed at getting more than a 2x performance improvement? Normally, a JIT is a 10-20x improvement in performance, just from the simple fact of removing the interpreter dispatch loop. What am I missing?
- seunosewa 4y agoDynamic language, which allows anything to be changed at any time.
- titzer 4y agoIt's clearly more complicated than that. JavaScript is also highly dynamic and JITs there often give 10-100x speedup.
- nicoburns 4y agoMy impression is that Ruby is more dynamic than pretty much everything else. I think this is true in terms of language features, but also in terms of the style that code is written in practice.
- pjmlp 4y agoThis tends to come up, also as reason why Python has yet to have a proper JIT, yet we have Smalltalk, Common Lisp, SELF and Dylan to prove otherwise. In Smalltalk's case, it was its JIT that ended up powering Hotspot.
- titzer 4y agoC2 was a clean rewrite by the Rice folks and C1 was, afaik, part of the Animorphic acquisition, which was written from scratch, though by Lars Bak and co who did indeed work on Smalltalk before. But AFAICT all they reused was the assembler.
- Alifatisk 4y ago> …many methods are direct translations of the Rust code into Ruby. Impressive
- foxandmouse 4y agoIs there any use of ruby in the deep learning space? It's my language of choice, but Python seems to be ubiquitous.
- cdiamand 4y agoIt looks like there was a little movement in the space not too far back: https://ankane.org/new-ml-gems https://ankane.org/new-ml-gems But I don't know how often this is used in production. I've ended up training the models in python and then loading them in Ruby.
- foxandmouse 4y agoThank you! I think I just need to embrace python and get over my hate of whitespace as syntax; People call ruby omasake, but at least I can structure it how I like.
- pjmlp 4y agoFrom compiler nerd point of view, this is great piece of work. Another meta-circular JIT implementation, instead of going the tried and through path that most keep on trailing. Looking forward how it evolves from there.