Optimizing Ruby lazy initialization in TruffleRuby with deoptimization
engineering.shopify.com
engineering.shopify.com
Ruby could have been Swift, if MacRuby had not been killed (well at least it lives on as RubyMotion).
It is all a matter of how much money one wants to throw at the problem.
Also ironically, some of the high performance libraries in macOS/iOS are still being written in Objective-C, despite the goal to replace them with Swift.
http://www.rubymotion.com/news/2019/03/01/the-sleeping-drago...
The problem is in developers. They are slow and dumb and lazy and most often also biased. Blaming language is easy. Bad developer will always write spaghetti no matter which language he uses.
Eh, not really.
I'm skeptical of your first point as well
Swift's raison d'etre is mobile development
And yes, MacRuby ( not Ruby ) could very much been Swift.
So... does that not mean that any micro-improvement would also be too small to be significant on any large project?
Microbenchmarking has nearly the entire resources of the machine available to itself. In live scenario, an arbitrary and unknowable mix of other code will be sharing those resources. We assert that we cannot model the negative - or positive - effects of that other code on the behavior of the code being benchmarked.
Except us workaday programmers do that in practice all the time. We hear about a performance improvement, we estimate the likelihood of a payoff, then we try it, first in isolation and then in our code. Sometimes the change is bad. Sometimes the change is boring. Occasionally, the change is surprising.[1]
Why couldn't we come up with test fixtures that run some common workloads and stick the code being benchmarked into the middle? You'd have 3 data sets instead of two in that case, control, A, and B. You will want to know how (A - control) relates to (B - control) as a fraction.
1. Biggest perf surprise I ever got (aside from the time I predicted the benefit of 4 optimizations in a row with a margin of error of <3%), I got a 10x when I expected 2x. We had two methods that got the same data from the database, filtered it, and compared the results. I moved the lookup to the caller and made them both pure functions (which helped with testing them). I don't remember chaining the calls, but even if I did, both methods were roughly the same cost, so that should have been 3-4x. The rest I suspect was memory and CPU pressure.
IIRc the reasoning goes along the lines of not wanting the risk of something being discontinued by a third party and having to shoulder the extra labor of supporting something with which the devs are not familiar.
I even contacted the devs at one point with a benchmark that ran jruby directly on strings for several minutes. The answer I got was always that it would eventually perform better than MRI with more warmup. Spoiler: it didn't. Well, maybe I was supposed to run it for another month and it would have.
It's worth thinking about JRuby-performance-skeptical-ness when thinking about TruffleRuby due to some similarities. Not going to outline in a comment, but suffice it to say that TruffleRuby was once called JRuby+Truffle.
TruffleRuby has the power to work through JRuby shortcomings. With GraalVM, TruffleRuby gets to have C extensions! Graal is also open source, so we get more control of what we want it to do and more understanding of what it does. In theory, that gives TruffleRuby more room to get faster.
It's also worth noting Charles Nutter's comment on the post, that mentions that Hotspot C2 already does this optimization! (though they wouldn't have this kind of control over branch profiling)
> TruffleRuby started as my internship project at Oracle Labs in early 2013. It is an implementation of the Ruby programming language on the JVM, using the Graal dynamic compiler and the Truffle AST interpreter framework. TruffleRuby can achieve peak performance well beyond that possible in JRuby at the same time as being a significantly simpler system. In early 2014 it was open sourced and integrated into JRuby for incubation, then in 2017 it became its own project, and now it is part of GraalVM. Since 2019 Shopify has sponsored development.
> In early 2014 it was open sourced and integrated into JRuby for incubation
Additionally, we also tried Truffle when it was JRuby, or in JRuby, however you want to put it, but without a lot of success. Things could be different now.
Also, I'm a sucker for Java but JVM-based things deployability just rocks.
That's not to say it doesn't exist: too many monkeys with internet-connected typewriters will eventually make every claim. But Google turns up a paltry 652 results for "Java faster than C"[0][1].
[0]: https://www.google.com/search?client=safari&rls=en&q=%22java...
[1]: On a related note, I found one of those Google searches with a single hit. Isn't there a name for that? It's "PHP faster than C"
Edit: I'm on a roll here. "Google faster than C" also gets one result: https://www.google.com/search?client=safari&rls=en&q=%22goog...
So what is a successful outcome you're hoping for with this project? Or is it purely academic?
Really? But now the latest results are in apparently and judging by these benchmarks[0], I don't know what to make of this claim given how slow TruffleRuby is when compared to other similar languages or even Ruby. But its clear that its LLVM-based cousin Crystal still blows it out of the ocean in every benchmark if you're really talking about 'high performance'...
But the benchmarks here don't lie and one can still say that in syntax similarity, Crystal is a 'faster and memory efficient Ruby with static types'.
Actually they don't even share the same syntax for declaring getters and setters. Honestly speaking I think people really only think of Crystal as "faster Ruby with static types" because they've mostly been exposed to C-style languages so anything that doesn't look like C just blurs together as "the same".
(Obviously Crystal is heavily inspired by Ruby, but there's a huge difference between "heavily inspired by" and "an implementation of".)
I totally expect base64 to perform like this though. It spends like one line in Ruby and then it's shipped off into the C extension, so really it's testing the differences between Sulong (LLVM bitcode interpreter for Graal) and a proper C compiler.