Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Make Ruby 2.6 Faster with JIT

Make Ruby 2.6 Faster with JIT

An introduction to MJIT in Ruby 2.6 and up. What does it do? How do you use it? How well does it work? What can go wrong?

Noah Gibbs

August 02, 2018

More Decks by Noah Gibbs

Other Decks in Programming


  1. Make Ruby 2.6 Faster with JIT Noah Gibbs, AppFolio @codefolio

    / engineering.appfolio.com Pictures are by Arthur Rackham, and are in the Public Domain.
  2. Thank You, AppFolio! AppFolio pays me to write and speak.

    Thank you, AppFolio! If you’re looking for a Ruby job in Southern California, talk to us!
  3. I Often Talk Too Fast. If you call out “hey,

    slow down!”, I’ll try to go slower. And it will help your fellow audience members!
  4. Compiling Ruby interprets your code as it runs. C++ (and

    others) compile to machine code before. “Compiling a C++ Program”
  5. JIT “Just-In-Time” compiling translates part of your app to fast

    machine code. “Running Faster Without Effort”
  6. Does JIT Work? (2) Ruby 2.6 experimental JIT is still

    prerelease. But it gets 2.5x+ for the same benchmark. “Ruby JIT Shows Early Promise”
  7. Tradeoffs of JIT Nothing is perfect. JIT has two main

    disadvantages: memory usage and warmup. “Considering JIT’s Tradeoffs”
  8. Memory Usage (1) JIT tracks method calls: • How many

    calls? • How much runtime? • With what argument types?
  9. Memory Usage (2) JIT keeps 2+ copies of a method

    and switches back to un-optimized if required. “De-optimizing a Method”
  10. Warmup JITted programs speed up as they compile methods. There

    is “warmup time” as new programs start out slower.
  11. Warmup vs Startup If compiling is high priority, early program

    speed is very slow. JVM is infamous for this. “Ruby Dancing with the JVM”
  12. Long Programs Servers and batch jobs benefit from JIT. Small

    quick programs get little or nothing. “Rake task dodging a JIT penalty”
  13. JIT and Ruby Core JIT’s disadvantages are Ruby advantages -

    memory, startup. JIT was a tough sell. “Core Dev Inspects JIT Attempt”
  14. JIT and Ruby Core After early JIT prototypes looked good,

    there was a bake-off. MJIT won. “Newborn Hope for Ruby Speed”
  15. How Does MJIT Work? MJIT uses a C compiler from

    a background job with a Ruby-to-C translator.
  16. How MJIT Differs (1) Each language’s JIT picks the CPU

    priority for compiling. MJIT is conservative. “MJIT’s Compiler at App Start”
  17. How MJIT Differs (2) MJIT compiles a bit at a

    time. So it has normal fast Ruby startup but long warmup. “JIT’s Usual Troubles”
  18. How MJIT Differs (3) JVM-style JIT compiles in-process. That runs

    faster, but can’t easily shed excess memory. “Attempting to Free Memory”
  19. How MJIT Differs (4) MJIT’s background job lets it discard

    memory after compile. But it pays a compiler speed penalty. “Invoking the Compiler”
  20. Using JIT in Ruby 2.6 In Ruby 2.6, you can

    turn JIT on with “--jit”. Try “ruby --help” to get args for JIT debugging and tuning.
  21. JIT With Rails? Takashi’s working on it. But for now,

    it slows Rails down. “Rails, Broken on JIT”
  22. Want JIT Off? In 2.6, JIT is off by default.

    Later, you can disable with “--disable-jit”. “Ruby JIT, Told to Go Away”
  23. Ahead-of-Time AoT is compiling fully at app start. Can Ruby

    JIT do that? Not really, no. “Minor Problems in Ruby AoT”
  24. Questions? “If You Have a Question, Somebody Else Wants to

    Know Too” These slides: https://bit.ly/southeast2018-gibbs