Live data from Hacker News

Ruby 3.3's YJIT: Faster While Using Less Memory

railsatscale.com

31–40 of 57 posts

Re: Ruby 3.3's YJIT: Faster While Using Less Memory

#31
post #19

My question is what's next? Without sacrificing (much) memory. We know from TruffleRuby that given enough warmups and lots of memory it could be multiple times faster than CRuby. And compared to Ruby 3.3 YJIT may be 2-3x faster. But it seems the communities as a whole cares a lot about memory usage. We know in order to make JIT more useful we need to move some of the Gems from C to Ruby. But other than that do we hav…

There is still lots of optimizations to make. On the JIT side, there is still no inlining, which opens the door to much more aggressive optimizations.

But also on memory as well. There was a lot of improvements done on the Ruby garbage collector for 3.3, but there's still a lot of room for improvement, and a few fine folks at Shopify are looking into making the GC swappable so we'd be able to use mttk GCs with MRI.

As for the community caring about memory usage, I wonder how much of that has to do with the default Heroku dynos. Because it's an issue for small scale deployment. Once you scale more, you recoup a lot with CoW etc, so it's much less of a worry.

Re: Ruby 3.3's YJIT: Faster While Using Less Memory

#32
post #23
post #13

Earlier quoted context omitted.

I benchmarked a good sized app (ran a black-box QA suite multiple times) while monitoring performance and req/response times with Prometheus/Grafana with Ruby 3.2. With YJIT enabled memory usage ballooned and performance dipped below non-YJIT Ruby 3.2, IIRC the difference was a good 10% degradation. Granted, it's an API only service so no HTML is being generated, only JSON and that could be the culprit. Suffice it to…

Interesting. Do you think html generation is one of the things that makes the numbers look so good for 3.2 YJIT? We run a mostly json api only app. I think json serialization is notoriously slow in ruby so I was hoping yjit would speed it up.

YJIT won't help JSON generation because it's all implemented in C (either the stdlib `json`, or `oj` or `yajl` etc.

If what is slow is some RUby code like Active Model Serializers etc, then maybe it can help a bit there.

But yes, generally YJIT works very well on HTML templates because they are compiled as large methods with not a lot of branches.

Re: Ruby 3.3's YJIT: Faster While Using Less Memory

#33
post #19

My question is what's next? Without sacrificing (much) memory. We know from TruffleRuby that given enough warmups and lots of memory it could be multiple times faster than CRuby. And compared to Ruby 3.3 YJIT may be 2-3x faster. But it seems the communities as a whole cares a lot about memory usage. We know in order to make JIT more useful we need to move some of the Gems from C to Ruby. But other than that do we hav…

> But it seems the communities as a whole cares a lot about memory usage. Matz very much sees Ruby as still a general purpose language that still supports scripting as a first tier concern. From that vantage bootup and memory are hugely important. Also providers like Heroku (I work there) charge for memory and the primary way to get parallelism with the GIL/GVL is using multiple processes where memory use can multipl…

I’m curious why you think constraints are such a problem? I’ve worked on quite a few large rails apps, and whilst you’re not wrong, the extra traffic from checking constraints has always been a tiny negligible part of overall db traffic.

Re: Ruby 3.3's YJIT: Faster While Using Less Memory

#34
post #25
post #19

My question is what's next? Without sacrificing (much) memory. We know from TruffleRuby that given enough warmups and lots of memory it could be multiple times faster than CRuby. And compared to Ruby 3.3 YJIT may be 2-3x faster. But it seems the communities as a whole cares a lot about memory usage. We know in order to make JIT more useful we need to move some of the Gems from C to Ruby. But other than that do we hav…

Truffle Ruby is 50-100% faster in most tests. But uses 5-10x more memory. Still has way more upside left to gain. https://railsatscale.com/2023-11-07-yjit-is-the-most-memory-...

Not to mention the warm-up time - the graph in the referenced article is measured in seconds, with max > 20!

Can attest, just pulled TruffleRuby (both native and JVM), it is over ten seconds to start a hello world script cold. As in, script being run from command line as needed.

These are gains that are only going to make sense for the long-running process crowd.

Re: Ruby 3.3's YJIT: Faster While Using Less Memory

#35
post #19

My question is what's next? Without sacrificing (much) memory. We know from TruffleRuby that given enough warmups and lots of memory it could be multiple times faster than CRuby. And compared to Ruby 3.3 YJIT may be 2-3x faster. But it seems the communities as a whole cares a lot about memory usage. We know in order to make JIT more useful we need to move some of the Gems from C to Ruby. But other than that do we hav…

Don't forget TruffleRuby's other tricks: parallel code [0] and polyglot language interplay [1] [2].

[0] https://www.graalvm.org/latest/reference-manual/ruby/#aim

[1] https://www.graalvm.org/latest/reference-manual/ruby/Polyglo...

[2] https://medium.com/graalvm/graalvm-ten-things-12d9111f307d

Re: Ruby 3.3's YJIT: Faster While Using Less Memory

#36
post #18

I think Ruby has at this point caught up to modern languages on everything except typing. Unfortunately the typing story is so poor that it still makes Ruby an incredibly difficult choice to justify in 2023.

For what use-case? Because I've been developing in ruby for over 10 years now and it has been the optimal choice for a ton of companies I've worked for. The lack of static typing is a feature for a lot of people.

Re: Ruby 3.3's YJIT: Faster While Using Less Memory

#37
post #31
post #19

My question is what's next? Without sacrificing (much) memory. We know from TruffleRuby that given enough warmups and lots of memory it could be multiple times faster than CRuby. And compared to Ruby 3.3 YJIT may be 2-3x faster. But it seems the communities as a whole cares a lot about memory usage. We know in order to make JIT more useful we need to move some of the Gems from C to Ruby. But other than that do we hav…

There is still lots of optimizations to make. On the JIT side, there is still no inlining, which opens the door to much more aggressive optimizations. But also on memory as well. There was a lot of improvements done on the Ruby garbage collector for 3.3, but there's still a lot of room for improvement, and a few fine folks at Shopify are looking into making the GC swappable so we'd be able to use mttk GCs with MRI. A…

can you share on this? :)

Re: Ruby 3.3's YJIT: Faster While Using Less Memory

#38
post #18

I think Ruby has at this point caught up to modern languages on everything except typing. Unfortunately the typing story is so poor that it still makes Ruby an incredibly difficult choice to justify in 2023.

Well, in ruby everything is an object that is a member of some class. Those classes have specific properties that only allow for specific methods to be applied on them. Ie, integers are members of the numeric::integer class, and if you want to use that integer as part of a string in output, you do have to convert it to a string first using a method defined as such.

So, what exactly do you see as missing in ruby's typing?

Re: Ruby 3.3's YJIT: Faster While Using Less Memory

#39
post #33

Earlier quoted context omitted.

> But it seems the communities as a whole cares a lot about memory usage. Matz very much sees Ruby as still a general purpose language that still supports scripting as a first tier concern. From that vantage bootup and memory are hugely important. Also providers like Heroku (I work there) charge for memory and the primary way to get parallelism with the GIL/GVL is using multiple processes where memory use can multipl…

I’m curious why you think constraints are such a problem? I’ve worked on quite a few large rails apps, and whilst you’re not wrong, the extra traffic from checking constraints has always been a tiny negligible part of overall db traffic.

It takes two seconds to add a “validated uniqueness” and now for every save or update instead of one SQL command to commit the data you’ve got 2 (multiplied by the number of validations). Plus this validation is weak in that it cannot protect from actual duplicate data.

These check queries are individually fast but put a tremendous load on a running app’s database. If you halve the number of queries the database has to process you’ll see more resources to process the slow queries in addition to each commit being faster.

It ultimately depends on the read/write patterns of the app, but most non-trivial rails apps do a bunch of writing AND reading.

My suggestion is less a “this will change the world forever” and more a “fairly clear win, we just have to do it”.

In a prior life I talked Sgrif into implementing it before David caused them to drop Active Record maintenance work.

I know the broad strokes but don’t have the need or mandate to implement it, plus the active record internals are pretty gnarly. Tons of modules, very little encapsulation. Very hard to know the correct place to put stuff, so stuff goes wherever. It’s gotten better from some of the work of Yehudah, Aaron, and Sage but AFAIK there’s no one on core who wants to own it right now. Eileen has done a lot of work recently, but I don’t think it’s her primary focus.

Re: Ruby 3.3's YJIT: Faster While Using Less Memory

#40
post #33

Earlier quoted context omitted.

I’m curious why you think constraints are such a problem? I’ve worked on quite a few large rails apps, and whilst you’re not wrong, the extra traffic from checking constraints has always been a tiny negligible part of overall db traffic.

It takes two seconds to add a “validated uniqueness” and now for every save or update instead of one SQL command to commit the data you’ve got 2 (multiplied by the number of validations). Plus this validation is weak in that it cannot protect from actual duplicate data. These check queries are individually fast but put a tremendous load on a running app’s database. If you halve the number of queries the database has…

> but AFAIK there’s no one on core who wants to own it right now.

Active Record is probably the "most owned" part of Rails, that's the one with the most core members and committers with deep knowledge of it.

As for your feature request, there's https://github.com/Shopify/activerecord-rescue_from_duplicat..., and we'd like to attempt to upstream that capability in Rails next year (but as everything it may or may not happen).

Post reply on HN