Live data from Hacker News

Ruby 2.6.0-preview2 released with JIT

ruby-lang.org

21–30 of 136 posts

Re: Ruby 2.6.0-preview2 released with JIT

#21
> We’re going to implement method iniling in JIT compiler, which is expected to increase Ruby’s performance in order of magnitude

An order of magnitude as in .. 10x? This seems too good to be true. Half the arguments against Rails melt away like butter if that's truly the case.

Anyone with a better understanding of the details care to comment on the likelihood of these performance gains being actually realised, and if not, what we might realistically expect?

Re: Ruby 2.6.0-preview2 released with JIT

#22
post #13

> Unlike ordinary JIT compilers for other languages, Ruby’s JIT compiler does JIT compilation in a unique way, which prints C code to a disk and spawns common C compiler process to generate native cod e. Oh dear god.

What's the advantage over using LLVM's built-in JIT, or PyPy's JIT, or generating machine code directly, or anything else that doesn't have the overhead of spawning processes for compiling and linking? One of the goals listed is minimizing the JIT compilation time.

Ruby on PyPy already exists: https://github.com/topazproject/topaz

Performance is disappointing, though.

Re: Ruby 2.6.0-preview2 released with JIT

#23
post #13

> Unlike ordinary JIT compilers for other languages, Ruby’s JIT compiler does JIT compilation in a unique way, which prints C code to a disk and spawns common C compiler process to generate native cod e. Oh dear god.

What's the advantage over using LLVM's built-in JIT, or PyPy's JIT, or generating machine code directly, or anything else that doesn't have the overhead of spawning processes for compiling and linking? One of the goals listed is minimizing the JIT compilation time.

yeah. even LLVM is very slow for a JIT. Ask any project using LLVM as a backend for a JIT and they'll tell you it's an recurring issue. See for example https://webkit.org/blog/5852/introducing-the-b3-jit-compiler...

I know very little about ruby specifically but IME for this kind of dynamic language you get most of the initial gains by :

- removing (by analysis or speculation) dynamic dispatch

- unboxing / avoiding allocations in the easy cases

Once you've done that, you can generate pretty dumb assembly and still come out way ahead of your interpreter (and avoid very costly optimization / instruction selection / regalloc / scheduling).

Most of what llvm / gcc do only make sense when you've got your code down close to whatever you would actually write in C.

Re: Ruby 2.6.0-preview2 released with JIT

#24
post #21

> We’re going to implement method iniling in JIT compiler, which is expected to increase Ruby’s performance in order of magnitude An order of magnitude as in .. 10x? This seems too good to be true. Half the arguments against Rails melt away like butter if that's truly the case. Anyone with a better understanding of the details care to comment on the likelihood of these performance gains being actually realised, and i…

For hot code, probably, not the entire language in general. If you're looping through a million numbers doing the same calculation, or maybe rendering markdown in a loop an a lot of text, might hit 10X - the JIT will essentially write the code in C for you, then compile it and run it instead of Ruby.

Re: Ruby 2.6.0-preview2 released with JIT

#27

> Unlike ordinary JIT compilers for other languages, Ruby’s JIT compiler does JIT compilation in a unique way, which prints C code to a disk and spawns common C compiler process to generate native cod e. Oh dear god.

It's the traditional method of doing a job equivalent to JIT. It has several examples in the history of computing, like SpamAssassin and Matlab (the latter if my memory serves me correctly).

Re: Ruby 2.6.0-preview2 released with JIT

#28
post #21

> We’re going to implement method iniling in JIT compiler, which is expected to increase Ruby’s performance in order of magnitude An order of magnitude as in .. 10x? This seems too good to be true. Half the arguments against Rails melt away like butter if that's truly the case. Anyone with a better understanding of the details care to comment on the likelihood of these performance gains being actually realised, and i…

Sinatra + Sequel is already very competitive in web performance with Go + Gin[1]. It's the Rails convenience stuff which slows things down massively. MJIT could probably bring Rails in line with Sinatra though.

Between Ruby 1.8 and 2.5, performance has improved around 13x in tight loops[2]. The Rails performance issue has been massively overblown since 1.9 was released.

Ruby 1.8 was a tree walking interpreter, so the move to a bytecode VM in 1.9 was a huge leap in performance. Twitter bailed to the JVM before moving to 1.9. A lot of those 10-100x performance differences to the JVM are gone thanks to the bytecode VM and generational GC.

Bytecode VMs all have the same fundamental problem of instruction dispatch overhead, they're basically executing different C functions depending on input.

Doing _anything_ to reduce this improves performance dramatically, even just spitting out the instruction source code into a giant C function, compiling it, and calling that in place of the original method. Another 10x improvement on tight loops should not be a problem.

[1] https://www.techempower.com/benchmarks/#section=data-r15&hw=...

[2] https://github.com/mame/optcarrot/blob/master/doc/benchmark....

Re: Ruby 2.6.0-preview2 released with JIT

#29

Earlier quoted context omitted.

I don't see why this is bad. Many compilers generate C

Not at runtime.

Varnish uses GCC to compile VCL into a dynamically loaded library. Not a general-purpose language, but it's done at runtime.

Re: Ruby 2.6.0-preview2 released with JIT

#30
post #13

> Unlike ordinary JIT compilers for other languages, Ruby’s JIT compiler does JIT compilation in a unique way, which prints C code to a disk and spawns common C compiler process to generate native cod e. Oh dear god.

What's the advantage over using LLVM's built-in JIT, or PyPy's JIT, or generating machine code directly, or anything else that doesn't have the overhead of spawning processes for compiling and linking? One of the goals listed is minimizing the JIT compilation time.

LLVM clearly wasn't designed for JIT. Don't let those letters "VM" confuse you; it's more like a machine abstraction than a virtual machine. And even that is far from water-tight.

But that doesn't mean you can't use a conventional compiler stack like LLVM as a JIT and get excellent code - it' just going to take its own sweet time doing so.

Can anyone think of any reasonably common stacks using LLVM as a JIT? There's mono, but that's a non-default mode; not sure if it's typically used. The python unladen-swallow experiment failed. Webkit had a short-lived FLT javascript optimization pass, but that was replaced by B3.

Which is just a long-winded way to suggest that LLVM is not likely to be ideal as a JIT, at least based on what past projects have done.

(Not trying to imply that writing C to disk is better, but it may well be simpler & more flexible - not worthless qualities for an initial implementation).

Post reply on HN