top | item 29161810

(no title)

angelbob | 4 years ago

Disclaimer: I'm on the YJIT team.

In general it's not a big change. You should only turn on YJIT for long-running jobs -- the prod Rails server, plus probably background workers if you have them. YJIT does nothing unless you turn it on with the --yjit flag.

YJIT's going to affect memory usage, so it'll change your optimal number of processes and threads for your Rails server - play with it for your app specifically, because the percent speedup and mem expansion vary a lot from app to app. YJIT works fine with Puma and Webrick. I don't think anybody's tried it seriously with less-common servers like Falcon or Thin, but I'd expect it to work -- file a bug if it doesn't, because it should.

YJIT does speed up Rails - we're seeing about a 20%-25% speedup on little "hello, world" Rails apps (see: https://speed.yjit.org/), and about 11% on Discourse for a single thread. We don't have good multithreaded or multiprocess numbers yet, but it's in the works. YJIT scales with multiple threads/processes just like existing CRuby.

(All speed numbers are accurate as of right now, but may change over time.)

I would probably not use it in dev mode. While YJIT has pretty good warmup numbers, Rails throws away all existing application code for every request in dev mode. That's going to make YJIT a lot less useful. Play with it -- maybe I'm wrong for your app, especially if you use a lot of non-reloaded code (e.g. methods inside gems.) But I wouldn't expect great results in the development RAILS_ENV.

For deployment the short version is: add --yjit as a command line parameter in production mode and (probably) for your background workers. You can do this with "export RUBYOPT='--yjit'" or use your local preferred way.

Where I give weaselly-sounding qualifiers like "probably," that's because it can depend on your config. If you have plenty of memory but are often CPU-bound, YJIT is usually good. If you have really limited memory and your server CPUs are mostly idle, YJIT is usually bad. YJIT is also currently x86-only and runs on Mac and Linux but not Windows.

There has been a lot of historical demand for a Ruby config for servers: something that uses more memory to get faster operations, and that is optimised for long-running processes. YJIT is aimed directly at that. Non-JITted CRuby is mostly the opposite: fast startup, modest memory requirements, doesn't get significantly faster over time.

discuss

order

xfalcox|4 years ago

> YJIT works fine with Puma and Webrick. I don't think anybody's tried it seriously with less-common servers like Falcon or Thin, but I'd expect it to work -- file a bug if it doesn't, because it should.

Have you tried it with Unicorn?

byroot|4 years ago

Yes, it work fine with Unicorn, YJIT is currently serving a small portion of Shopify storefront traffic, and that app runs with Unicorn.

Of course since each of the unicorn process will generate its own executable code, the memory usage difference with Puma is even bigger, and copy on write can't help here.

pqdbr|4 years ago

How one would check if the YJIT was correctly enabled?

byroot|4 years ago

    $ ruby -v
    ruby 3.1.0dev (2021-11-08T09:35:22Z master 7cc4e147fc) [x86_64-darwin21]
    $ ruby --yjit -v
    ruby 3.1.0dev (2021-11-08T09:35:22Z master 7cc4e147fc) +YJIT [x86_64-darwin21]
    $ ruby --yjit -e 'p RubyVM::YJIT.enabled?'
    true
    $ ruby  -e 'p RubyVM::YJIT.enabled?'
    false

sebiw|4 years ago

You can call `RubyVM::YJIT.enabled?` to check.

claudiug|4 years ago

can we expect for better numbers on the official 3.1 release, or we need to wait for 3.2 version?