00:00:08.679
I'm really glad to have someone here to talk about JRuby. JRuby is a big deal, and you should all be paying attention to it. I'm really happy to have Charlie Nutter here; he's at Red Hat and is one of the principal minds behind JRuby. He works on JVM languages at Red Hat, doing a lot of cool stuff.
00:00:16.880
He's going to tell you about making Ruby high performance. Thank you, Charlie.
00:00:39.000
All right, I have to ask the usual introduction questions. How many people here have ever used JRuby for something? Wow! How many people are using it for something in production right now? Okay, fewer, but we're getting there; a lot more people have tried it out, which is promising.
00:00:52.879
I'm going to talk specifically about JRuby and how we're trying to optimize Ruby. More generally, I will discuss the challenges we face and some of the ways we are looking to make Ruby faster and actually turn Ruby into a higher performance language.
00:01:11.439
So, basic contact info: I am one of the JVM language guys at Red Hat, specifically in the JBoss Polyglot group, which is working on polyglot web server applications and services within JBoss. I'm mostly focused on JRuby right now, but hopefully after JRuby 1.7 is done in the next month or so, I will start looking at applying what we've learned to some of the other JVM languages as well.
00:01:41.439
What does performance mean when it comes to Ruby? There are usually two metrics people refer to regarding Ruby performance. First is the classic idea that man-hours are more expensive than CPU hours. Ruby may not be the fastest language, but we can write applications quickly and maintain them easily. Users are generally happy when they use Ruby. By this measure, Ruby can already be considered a high-performance language if the goal is to write and maintain applications efficiently.
00:02:31.160
However, I will be discussing the other definition of performance, which typically relates to the bottom line of older applications as they grow larger. We need to improve the raw performance of running code and make it better within Ruby.
00:03:09.599
So what is high performance? High performance means being faster than other Ruby implementations. It's something I personally care about, ensuring we can achieve better performance compared to managed languages like C. People often claim Ruby isn't as fast as Java, .NET, or other systems, which raises the question of whether it can be considered high performance when it lags behind.
00:03:49.519
Unmanaged languages like C have raw performance benchmarks we want Ruby to match or even exceed someday. But the real question is, is that a reasonable goal? And do we even need to reach that goal? High performance should really mean that it's fast enough for the tasks you need to accomplish.
00:04:19.639
For example, if you're running a website or a Rails application, achieving high performance may not be a daunting challenge, especially if you have other backend services doing heavy lifting. However, we want the flexibility to use Ruby throughout our systems without needing to rely on alternatives constantly.
00:05:03.919
Many have claimed that Ruby 1.8.7 was fast enough, but now that 1.9.3 has been released, it’s considerably better. The new phrase is that now 1.9.3 is fast enough, but what about those who found 1.8.7 satisfactory? Were they lying, or did they simply not need the performance gains offered by 1.9.3?
00:05:44.520
For any growing application, there will come a time when ‘fast enough’ won't be sufficient. You might hit a performance wall when you can't manage to get the necessary work done given your CPU and monetary resources. In that case, options include moving to a different runtime or even back to an earlier version like 1.8.7, or seeking a performance hit with C extensions, which can often lead developers astray.
00:06:25.520
One of my claims is that if you aren’t writing performance-sensitive code in Ruby, you might be giving up too easily. There are other methods for improving performance, and JRuby is one of them. We'll explore how we are working to enhance Ruby's performance.
00:07:03.360
Many developers fall back on native extensions to gain performance boosts. While integrating existing libraries whose functionality isn’t available in Ruby is not a universally bad idea, the current C API for extensions is quite invasive.
00:07:31.200
It allows for direct access to pointers and requires developers to interact with the internals of objects frequently. As a result, unless you're using Ruby MRI, support for this API can be quite limited, and even MRI itself can struggle operationally to provide resources. Out of Ruby's performance goals, it’s crucial to run code faster, and this may involve incorporating a JIT compiler or enhancing garbage collection.
00:08:51.680
Even with Ruby 1.9.3, extensive GC pauses have been reported in production applications. The overall CPU consumption from GC often falls within the 10 to 20% range, which is wasted cycles. To combat this, we require a more efficient GC system. Furthermore, we strive to enable parallel execution to effectively utilize all cores without launching numerous processes.
00:10:24.240
As Ruby applications grow in size, the performance hit from GC can exacerbate as the application continues to accumulate objects in memory. This results in longer scan times for Ruby’s GC, consuming time and processor resources.
00:11:13.360
Unfortunately, the methods available for C extensions impede progress. C extensions require pointer access, which means it is impossible to shift memory locations. For example, relocating older data into a GC-free zone to avoid being collected by GC would not work.
00:12:10.160
Building a JIT that seamlessly works with C extensions is significantly more complex under current practices. Furthermore, parallel execution lacks guarantees due to uncertain native code writing, as no standardized memory models or guidelines exist for implementing parallelism with C extensions.
00:12:53.760
This is where a different approach may come in: instead of turning to C and its extensions, we ought to ask if we can enhance Ruby itself to be considerably faster. We have two options for improvement: either building our own runtime or using an existing performance-optimized runtime.
00:13:48.640
JRuby represents the latter choice—leveraging the JVM. By incorporating JVM's design, we benefit from 15 years of engineering effort, especially concerning technologies like OpenJDK HotSpot. This open-source runtime is recognized for its extreme performance benefits. It undoubtedly surpasses managed runtimes, outperforming .NET in comparative benchmarks.
00:15:29.960
Moreover, the JVM has the finest garbage collectors currently available, attributed to innovative research over the past decade. The HotSpot VM features six distinct GC options that utilize parallel processing and significantly reduce pause times, allowing for guaranteed short pauses.
00:16:58.800
The major JVMs have successfully resolved the intricacies of implementing parallel threading, which JRuby can take advantage of while developing. Additionally, the broad platform support offered by the JVM includes many server operating systems, ensuring that JRuby functions anywhere.
00:18:15.440
It is worth addressing a lingering misconception that Java is slow; although it faced this criticism historically, Java has emerged as a rapid, high-performance language. Developers often misinterpret Java's speed due to the extensive level of abstraction required when building applications, which detracts from performance.
00:19:43.520
Consequently, while mathematically equivalent algorithms may compile down to similar assembly code between Java and C/C++, the way you write code will drastically impact your performance, regardless of language.
00:20:24.960
Finally, JRuby combines the best of both worlds by bringing Ruby to the JVM while also integrating JVM capabilities directly into Ruby. JRuby 1.6 was released with solid Ruby 1.9.2 support while JRuby 1.7 is on the cusp of better 1.9.3 support.
00:21:18.560
Jruby maintains the same memory and threading models as the JVM. Everything is inherited, ensuring that we can eventually JIT compile Ruby code into JVM bytecode that can then be transformed into native code.
00:23:04.160
Optimizing Ruby's execution has proven to be a long road as nobody has discovered all the ‘magical’ solutions to making Ruby fast across the board. Over the prior six years, JRuby has made remarkable strides, but numerous challenges remain, with particular methods still defying optimization.
00:24:50.440
Efforts continue in enhancing JRuby performance, ensuring string, array, and hash methods run rapidly without significant performance issues. The commitment is to repeat this optimization process until we find effective strategies.
00:25:44.760
In examining the evolution of JRuby, it can be traced back to 2001 with the first contributions arriving over time. Following an initial burst of activity, development stagnated before reviving under Tom Enebo and eventually expanding when I joined forces in 2005 to revitalize the interpreter. It was in 2006 that we grasped a significant momentum due to firm connections at Sun Microsystems.
00:26:57.520
As of today, the activity level remains robust, dedicated to continuing the upgrade of JRuby, aligning the system's execution with what the JVM expects to improve performance for Ruby arguments and eliminating excessive overhead in the process.
00:28:46.960
The core tenet of performance optimization is eliminating unnecessary work. Different components within Ruby, such as modules and classes, comprise maps that could lead to wasted cycles. Simplifying method lookups aids in reducing overhead, and we can cache methods for improved access.
00:29:43.760
Handling constant lookups is slightly more intricate due to variations in lexical scopes, requiring a reliable system without excessive overhead. By architecting instance variable access effectively, Ruby can sidestep the traditional hashing overhead, ultimately saving on unnecessary compute resources.
00:30:37.680
Implementing invoke dynamic serves as a vital tool to aid JRuby. Invoke dynamic provides more freedom over method invocation and other dynamic behaviors, leading to performance improvements. This includes areas such as dynamic typing and instance variables, which aren't statically defined but require runtime decision-making.
00:31:29.640
Within the JVM, there are 200 operations available. Among them, 10 to 16 act as data endpoints for various methods. Emphasizing performance, JRuby effectively employs invoke dynamic to enhance the efficiency of its execution, and this agility holds benefits for JRuby compared to other Ruby implementations.
00:32:35.520
By capitalizing on the capabilities of invoke dynamic, JRuby can sidestep limitations imposed by standard JVM operations, thereby optimizing the Ruby execution pathways.
00:33:39.680
The success of JRuby's optimization efforts will be marked by effective benchmarking. While benchmarking poses its own challenges, especially in a dynamic optimization context like the JVM, the ability to monitor how the JVM dynamically changes its optimizations helps demonstrate the program's performance.
00:34:59.840
Instead of relying solely on synthetic benchmarks, we need real-world applications that accurately represent expected workloads. Therefore, our future testing must shift focus toward substantial applications to truly measure JRuby's performance under load.
00:36:13.920
As we explore the robustness of JRuby, we seek metrics relevant to significant frameworks such as Rails, which relies on core Ruby classes requiring optimization for maximum efficiency. Recognizing these complexities ensures that we develop solutions designed for these challenging areas.
00:37:48.080
In conclusion, our objective is to enhance JRuby performance continually. With its development being an iterative process, we are committed to identifying areas for improvement while remaining open to community feedback regarding which enhancements would best support the many Ruby frameworks.
00:39:19.480
JRuby will progress, with strides toward optimization and enhancements from the ongoing efforts. Given its open-source capabilities, it is an ideal time to explore JRuby options and gauge its potential for transforming your Ruby applications. Thank you.
00:40:05.920
Okay, apparently I've timed this exactly at 45 minutes.
00:40:10.760
Long.