[HN Gopher] Optimizing Ruby lazy initialization in TruffleRuby w... ___________________________________________________________________ Optimizing Ruby lazy initialization in TruffleRuby with deoptimization Author : kipply Score : 127 points Date : 2020-04-11 14:28 UTC (8 hours ago) (HTM) web link (engineering.shopify.com) (TXT) w3m dump (engineering.shopify.com) | kipply wrote: | (btw I am the author of this post, thread questions if wanted. | Trying to avoid draining myself addressing all the comments. Take | care in these strange times <3) | joelbluminator wrote: | So what's Shopify's goal in supporting TruffleRuby ? isn't Ruby | 3x3 promise good enough? Is Shopify looking to optimise memory | footprint or speed or both? | kipply wrote: | I think "good enough" is not a perfect mentality for what we | want from our services. Ruby 3x3 is great (3 times faster is | insane!), and we are looking at many things to optimise Ruby. | TruffleRuby does aim to get more than 3x faster (already does | on optcarrot) and could also provide some insight to be | applied elsewhere. Other reasons include TruffleRuby features | such as Chrome dev tools debugging (I'm not endorsing it as | superior or inferior to any existing Ruby debugging tools) | and polyglot programming. All in all, the goal is most | accurately described as "research". | kipply wrote: | As a general comment about production applications, memory is | less important than speed since computers are cheap compared | to having poorer user experience. Also, with JITs, consuming | less memory isn't that realistic. You can find "complaints" | about Pypy and Java and consuming a lot of memory. | joelbluminator wrote: | > All in all, the goal is most accurately described as | "research" | | So what is a successful outcome you're hoping for with this | project? Or is it purely academic? | kipply wrote: | Not really sure there is a good answer for this. A past | successful outcome was that we could actually get | TruffleRuby to run an entire production application | without code-changes. I suppose a future one could be | that it's easy, fast and good to develop and ship an | application running on TruffleRuby. | saagarjha wrote: | How close to that goal is TruffleRuby right now? | jrochkind1 wrote: | > Benchmarking isn't a perfect measure of how effective this | change is (benchmarking is arguably never perfect, but that's a | different conversation), as the results would be too noisy to | observe in a large project. | | So... does that not mean that any micro-improvement would also be | too small to be significant on any large project? | hinkley wrote: | I kinda suspect it may be time to restate the problem and | revisit it. | | 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. | kipply wrote: | This particular one is. Maybe we could measure time-to-warmup | or hot performance and with extremely careful scientific | process we can say X application has sped up by Y percent. It | also would not be helpful, because we know that it's a micro- | improvement. Having data on the results of this improvement in | the context of compilation speed and machine code output is | useful, since it tells us that it's not a micro-un-improvement | and because that was the intermediary goal in this | optimization. | trimbo wrote: | This was my question as well. If the change can't be measured | even with a benchmark, what is the goal? | kipply wrote: | The goal of the blogpost was less about talking about this | optimization and more introducing TruffleRuby and making | changes to programming language implementations at a high | level understanding. The goal I had when I started working on | the feature, was to introduce myself to TruffleRuby and was | actually my first PR. It's not an impressive change, but it | helps get into a lot of the important aspects of how | TruffleRuby is engineered. | pjmlp wrote: | Nice to see some TruffleRuby love. | | Ruby could have been Swift, if MacRuby had not been killed (well | at least it lives on as RubyMotion). | twic wrote: | Ruby? It's Dylan that could have been Swift: | | https://en.wikipedia.org/wiki/Dylan_(programming_language) | pjmlp wrote: | Indeed, but that was with the old Apple, hence why I left it | out. | RussianCow wrote: | Ruby is inherently much too slow to have ever been a Swift. All | of its dynamic runtime features give it a pretty low | performance ceiling compared to a statically typed, compiled | language with very limited runtime introspection/reflection. | ksec wrote: | I think it is important the parents was referring to MacRuby | [1], which is a very different Ruby Implementation than | current CRuby. | | And yes, _MacRuby_ ( not Ruby ) could very much been Swift. | | [1] http://macruby.org | masa331 wrote: | BS. Ruby isn't slow. The same apps can be written in pretty | much any language nowadays. | | 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. | mailslot wrote: | It's both. Ruby IS slow. If you ever need to create a tree | structure that isn't available in a natively-compiled Gem, | you'll know what I mean. | SaxonRobber wrote: | This is only true if your applications are mostly high | level glue. | pantulis wrote: | Which is what most "business" apps are anyway. | [deleted] | speedgoose wrote: | While it's still very slow, modern Javascript VMs are fast | enough for many usages. Ruby is slow, but it could be a lot | faster with a lot of time and money. | bnt wrote: | But developing in JS is consideray slower than in Ruby, and | time to market should be king. | tln wrote: | On a mobile device, efficiency should be king... that's | not exactly Ruby's forte | | I'm skeptical of your first point as well | bnt wrote: | How does backend development reflect on mobile? | tln wrote: | "Ruby could have been Swift" | | Swift's raison d'etre is mobile development | saagarjha wrote: | > time to market should be king | | Eh, not really. | kipply wrote: | V8 is a work of art <3 | pepemon wrote: | What do you like the most in the V8 internals? | kipply wrote: | It's not nice to pick a favourite child. Though something | I heard about recently that made me happy (less about V8 | internals) is how they try not to improve compilation | speed by not compiling. There isn't a video about it yet | but you can stalk https://2020.programming- | conference.org/details/MoreVMs-2020... when it exists | saagarjha wrote: | JavaScript VMs are quite fast, actually. They get a lot of | attention. | pjmlp wrote: | Common Lisp, Dylan kind of prove otherwise. Also RubyMotion | isn't that slow either from what I can tell. | | 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. | stephenhuey wrote: | RubyMotion is awesome but it should be noted that | RubyMotion apps are statically compiled for each native | platform. Also note that it has been rebranded to | DragonRuby: | | http://www.rubymotion.com/news/2019/03/01/the-sleeping- | drago... | The_rationalist wrote: | I wonder if ruby could eventually officially migrate to Graalvm | riffraff wrote: | that is unlikely, matz mentioned a few times how adopting | something developed elsewhere as a core vm was something he | didn't want to do. | | 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. | The_rationalist wrote: | It's open source, they could get familiar with it and not | depend on anybody? | rvz wrote: | >'TruffleRuby has high potential in speed, as it is nine times | faster than CRuby on optcarrot, a NES emulator benchmark | developed by the Ruby Core Team.' | | 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'... | | [0] https://github.com/kostya/benchmarks | [deleted] | kipply wrote: | There are four benchmarks in there that compare CRuby and | TruffleRuby and two of them are slower. TruffleRuby is 2x | faster on bench.b (brainfuck implementation), 3x faster on | matmul, 3x slower on base64 and 7x slower on json. All four of | these are pretty specific benchmarks. Optcarrot has code that | is much more representative of what a Ruby program might look | like. | tom_mellior wrote: | In addition, it's interesting to see that TruffleRuby does | better than CRuby on the longer running benchmarks, and worse | on the shorter ones. The page claims that JIT warmup "is | applied when necessary", but there are no further details. If | I had to bet, I would guess that in the case of TruffleRuby | maybe not enough warmup is being done in these experiments. | kipply wrote: | That sounds likely, but if it's not warmed up in some | amount of time that a decent programmer believes to be | enough, that probably means that it's warming up too | slowly! With that being said, it could also mean that the | faster ones could be even faster. | | 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. | oweiler wrote: | Crystal is not Ruby. | rvz wrote: | Although I didn't say it was, you're actually half right | since its an inspiration of Ruby even when some code compiles | 1:1 with Crystal; the same inspiration can be also said for | Elixir. | | 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'. | filleduchaos wrote: | > 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".) | empath75 wrote: | Not technically but it can run a lot of Ruby code with no | changes. | filleduchaos wrote: | That is a very, _very_ dubious claim indeed considering | that even stuff as trivial as `attr_reader`, `attr_writer` | and `attr_accessor` go by a different name in Crystal. | ericb wrote: | I remain skeptical of JRuby. As of about 2-3 years ago, there | were many benchmarks touting it's performance, but in our large | publicly deployed web app, it always underperformed and switching | to MRI on Phusion more than doubled our performance on half the | servers. We also spent like a developer-year on issues that | accompanied being off the beaten path with JRuby, like various | nokogiri complications. | | 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. | Pmop wrote: | Haven't tested this but I feel like JRuby will really exceed | only if the solution to your problem benefits from hardcore | multi-threaded computations, for not having a GIL in this case | diminishes the added JVM overhead. | | Also, I'm a sucker for Java but JVM-based things deployability | just rocks. | MoOmer wrote: | This article is about TruffleRuby, not jruby. | kipply wrote: | Sorry to be a bit overbearing here~ | | 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) | sdegutis wrote: | IIRC TruffleRuby is implemented very differently than JRuby | and has a lot more potential. So I'm not sure any | comparisons can really be made. | ericb wrote: | source: https://chrisseaton.com/truffleruby/ | | > 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. | sdegutis wrote: | I interpreted that sentence as meaning it was integrated | into the JRuby project as a "home" for the project, | similar to being under the management of a particular | github org. Not that its implementation was in any way | changed or integrated into JRuby. | [deleted] | mailslot wrote: | Sounds like every other believer of the JVM. I've been reading | about how Java outperforms C for 20+ years now. When it doesn't | even come close, someone faithful of the JVM insists that I try | some new garbage collector or wait for the next release. | IAmEveryone wrote: | Funny, I managed to spent a similar time in this industry and | cannot remember any claim of Java being faster than C. | | 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=%22 | java... | | [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=e | n&q=%22goog... | saagarjha wrote: | Java running on a good VM such as HotSpot can outperform C | in certain cases. ___________________________________________________________________ (page generated 2020-04-11 23:00 UTC)