Just-In-Time Compilation

JRuby 2018: Real World Performance

JRuby 2018: Real World Performance

by Thomas E Enebo and Charles Nutter

In the talk titled "JRuby 2018: Real World Performance" presented by Thomas Enebo and Charles Nutter at RubyConf 2018, the focus is on the advancements and performance improvements in JRuby, a Ruby implementation on the Java Virtual Machine (JVM). The speakers emphasize the compatibility of JRuby with pure Ruby gems and its advantages, particularly in performance when compared to CRuby. Key points covered include:

- JRuby Goals: Making JRuby as user-friendly and compatible as CRuby, with adaptations for native C extensions.

- JVM Benefits: Leveraging the JVM allows JRuby to utilize native threads, achieving efficient CPU core saturation and thereby optimizing performance in multithreaded applications.

- JRuby Versions: Current support includes JRuby 9.1 for Ruby 2.3 and 9.2 for Ruby 2.5, with plans to phase out Ruby 2.3 support as new Ruby versions are released.

- Performance of JSON Processing: Benchmarks demonstrate JRuby's efficiency, particularly against CRuby, showcasing its performance gains in handling JSON data and its overall speed in data processing tasks.

- Rails Optimization: JRuby's compatibility with Rails applications has improved significantly, with high test success rates and support for major database adapters.

- Future Enhancements: Introduction of a new JIT compiler, Graal, promises performance enhancements, alongside memory optimization efforts to further reduce overhead.

- Community Contributions: The development thrives on community input, encouraging developers to contribute to JRuby's evolution, particularly for new Ruby features.

- Real-World Applications: Anecdotes of existing implementations—like NASA's usage—highlight the practical capabilities of JRuby in diverse environments.

The talk concludes with an encouragement to explore JRuby, emphasizing its suitability for modern application development, especially in resource-intensive environments. By optimizing memory usage and leveraging the JVM’s capabilities, JRuby presents as a compelling alternative to CRuby, particularly for larger applications requiring enhanced scalability and performance.

00:00:17.070 Thank you for coming today. I'm Tom Enebo, and this is Charles Nutter. We are the JRuby team. Together, we have been working on JRuby for a combined total of 12 years, with over 30 years of experience working together. Red Hat has been gracious enough to employ us to continue our work on JRuby.
00:00:38.730 Recently, we've been receiving a lot of questions regarding Red Hat's acquisition by IBM. While we don't really know what this means for us as we continue to navigate through this process, it seems the deal will take a long time to finalize. We're curious to see what will happen.
00:01:03.960 Today, we will be talking about JRuby. How many of you are familiar with JRuby? Have you used it before? It's great to see that most of you are already familiar with it. Our goal with JRuby is to make it a Ruby implementation that feels as similar, easy, and friendly to use as CRuby.
00:01:15.750 We want it to work seamlessly. Essentially, all pure Ruby gems should work correctly, minus a few implementation bugs we continue to address over time. If something doesn't work as expected, it's likely our issue, so please let us know, and we will strive to fix it. Generally, you can expect a solid experience.
00:01:52.619 There are many C extensions available, and we currently support most of the major ones like Nokogiri, Jason, etc. We'll discuss compatibility with C extensions a bit later. It's important to note that, while we prioritize being a Ruby implementation, JRuby is also a JVM language, which provides us access to the full power of the JVM platform.
00:02:09.959 This includes access to powerful tools such as VisualVM, which is part of OpenJDK. This tool provides a live view of the JVM garbage collector, showing the different generations filling up and being collected, how much CPU time is being spent, and the overall heap size. You can see a visual representation of how garbage collection is functioning.
00:02:54.959 Since JRuby runs on the JVM, it can utilize real, native parallel threads. This means that a single JRuby instance can saturate all the CPU cores in your system. For instance, you could run JRuby on an 8, 16, or 32 core system and have a single process handle your entire application, rather than needing multiple processes as is standard with CRuby.
00:03:41.310 We also gain access to exciting features on the Java platform. For example, there is a Minecraft plugin using the JRuby-based Ruby API that allows for modifications like changing the number of chickens that hatch from an egg. Tom has a humorous story about using this plugin so extensively that he ended up creating an overload of chickens in his Minecraft world.
00:04:11.310 We now support two versions of JRuby: 9.1, which provides support for Ruby 2.3, and 9.2, which supports Ruby 2.5. We've chosen to skip support for Ruby 2.4.
00:04:23.650 We have plans to retire support for Ruby 2.3 and will offer at least one more point release for it. If this concerns you, please come and speak with us afterward. We want to understand how invested you are in Ruby 2.3 and what we might be missing in 9.2.
00:04:50.260 If you are still using Ruby 2.4 or earlier, please let us know your concerns, although we believe that transitioning from 2.3 to 2.4 or 2.5 is fairly straightforward. We are not planning to focus heavily on our Ruby 2.3 support as Ruby 2.6 is due to be released this Christmas, and we want to manage our support effectively between JRuby 9.2 and 9.1.
00:05:14.770 We've been making rapid progress—just in the last week, we released four point updates, making up for lost time. While we are committed to timely updates, we plan to stabilize our release schedule to about once a month or six weeks. This brings us to the future.
00:05:57.620 JRuby has a wealth of new features coming with every new Ruby version. This is a great opportunity for anyone here to contribute to JRuby. Some portions of JRuby are implemented in Ruby, so if you see a new Ruby feature or an addition, feel free to submit a patch. Generally, a Ruby implementation is perfectly acceptable, though there are performance-critical cases where we may transition it to Java.
00:06:54.110 The JRuby development has thrived with community contributions, and we maintain communication through our IRC channel on Freenode or our GitHub JRuby room. We are also available on Twitter and via email for any questions or help you may need.
00:07:06.690 When it comes to library compatibility, pure Ruby libraries run effectively on JRuby, including Rails and Rake, which function just as they do in CRuby. If you have a pure Ruby library that isn't performing how you expect, please inform us, and we will investigate possible issues on our end.
00:07:31.310 We have support for many native extensions, and Tom will speak more about some ongoing developments in this area. Our focus has also included optimizing our support for the Oj JSON library, particularly as developers have requested more compatibility.
00:08:10.640 A challenge we face is that while many developers use Oj as a direct dependency, it is also often included as a transitive dependency, making it challenging to switch to JRuby since it’s a native C extension. Given that Oj is quite large—nearly 20,000 lines of C code—we need an effective compatibility layer.
00:08:56.790 We aim to simplify this process and currently have a Java-compatible JSON implementation that's about half the size of the Oj implementation. We are diligently working to complete the remaining features and fix existing bugs, as we're committed to rolling out the complete Java version soon.
00:09:36.040 Points of comparison highlight the performance advantages of using JRuby. For instance, benchmarks show that running JRuby with the standard JSON library shows a significant performance increase compared to Oj with both JRuby and CRuby.
00:10:03.740 Particularly in cases of data processing and generation, JRuby performs with an impressive advantage. In many scenarios, JRuby outperforms CRuby, solidifying our case for JRuby's efficiency in handling large JSON payloads.
00:10:43.960 Shifting gears to Rails, we have been running Rails applications since 2006, and many have successfully deployed JRuby on Rails. Initially, we had difficulties keeping pace, particularly with Active Record and JDBC as the corresponding functionality lagged.
00:11:20.150 However, we have since resolved these issues, and our results when testing against Rails 5 have been promising. While we've encountered some problems, such as a lack of support for forking processes, we maintain a high success rate with nearly 99.9% of Rails tests passing.
00:12:05.700 Although there are still some non-passing tests that need attention, we are committed to resolving these. If you have specific timing concerns, please let us know so that we can address your requirements.
00:12:42.800 In general, the consensus is that you can run Rails applications on JRuby right now without encountering significant problems. We will mainly support the big three database adapters, with additional community support for MS SQL.
00:13:26.970 For databases like Oracle and DB2, we recommend third-party gems, such as Oracle Enhanced.
00:13:53.420 Now, let's dive into performance, which is a key focus of today's discussion. JRuby employs a mixed mode architecture featuring its own interpreter and compiler. The Ruby code gets parsed and compiled to our internal representation. As we recognize frequently used methods, we compile them to JVM bytecode for better performance.
00:14:39.880 JVM itself is a mixed mode runtime as well, enhancing efficiency, especially for Ruby. I'll demonstrate some micro-benchmarks that showcase the performance gains we've achieved. With the added feature of invokedynamic introduced around Java 7, our Ruby calls and constants have become more efficient, leveraging optimizations similar to that of Java.
00:15:33.970 It's important to note that while benchmarks are fun and can highlight improvements, they are not always indicative of real-world applications. Nevertheless, they illustrate a consistent improvement over time.
00:16:00.530 We are encouraged by the performance improvements from invokedynamic. For example, benchmarks with different implementations show clear indicators of how JRuby speeds up typical processing tasks, especially in percentage gains over CRuby.
00:16:54.630 Moving forward, a new JIT compiler called Graal has surfaced, offering improved optimizations beyond the standard JVM JIT. If you're interested in exploring it, we can guide you on how to enable it within JRuby.
00:17:39.020 What we have seen thus far with Graal indicates transformative performance increases—on some benchmarks, we're witnessing performance enhancements up to 20 times over CRuby.
00:18:17.610 Along with optimizing memory management, we aim to reduce object indirection by creating specialized types for instance variables. This allows us to effectively manage memory use and reduce the overhead typically seen in Ruby applications.
00:19:10.980 With improvements in how object and array memory is structured, we're excited to report a significant reduction in memory usage for JRuby applications. We aim to integrate both instance variable optimizations and array styling improvements to produce more efficient memory-use scenarios that save resources.
00:20:01.760 It's important to bear in mind that Rails performance hinges largely on Active Record. Since Active Record consumes substantial CPU resources, we've developed benchmarks around create, read, and update operations to gauge performance accurately.
00:20:43.780 Comparing these benchmarks reveals that while JRuby may lag slightly in create operations, it ultimately surpasses CRuby in both read and update performance, offering an overall increase in speed and efficiency.
00:21:45.210 As your application scales, a huge benefit of JRuby arises. What we can offer is a more efficient threading model compared to CRuby, which relies heavily on multi-process architectures.
00:22:40.790 By consolidating your JRuby processes into one single multi-threaded instance, you can reduce overhead and improve resource-sharing capabilities significantly.
00:23:10.870 Through benchmarking, our results show that a full-stack, scaffolded JRuby application can operate around 30% faster than its CRuby counterpart. This performance improvement may vary based on your specific application's load and operations.
00:24:04.920 After warming up, JRuby shows impressive performance advantages, leveraging its threading capabilities to manage resources optimally and efficiently. Users deploying JRuby applications in high-demand contexts will notably benefit.
00:24:55.030 Of course, it's worth mentioning that while JRuby uses more memory than CRuby due to the JVM's architecture, the performance benefits often far outweigh this overhead.
00:25:28.890 With the ability to scale efficiently, JRuby provides an attractive alternative to CRuby for larger applications, particularly in cloud environments where memory usage directly impacts costs.
00:26:05.510 We're excited to highlight that, based on our evaluations, JRuby is currently the most effective way to run Rails applications, with substantial speed improvements for CPU-intensive tasks.
00:26:42.960 Furthermore, we are exploring method inlining optimizations to enhance performance further. Method inlining can eliminate the overhead of method calls, thereby providing a noticeable boost in execution speed.
00:27:06.410 However, a limitation arises when our method calls involve passing blocks, as these currently can't benefit from inlining due to type checking.
00:27:45.830 We've implemented our method inlining feature, which treats method calls and blocks as unified units, allowing for inlining where applicable, provided both are in Ruby.
00:28:12.960 As we strive for optimization, we can enhance how we utilize Ruby methods at runtime to speed up operations dramatically.
00:28:44.930 In conclusion, if you're using an installer like RVM to manage your Ruby environments, you can easily install JRuby to access the latest features. We greatly value our user base and appreciate the contributions from those utilizing JRuby for production applications.
00:29:37.430 With its capability to run Rails applications efficiently across different environments, especially Windows, JRuby is well-suited for modern application development.
00:30:18.590 For those running on Java 9 or higher, we are optimizing to work more seamlessly with the stricter encapsulations introduced in newer versions.
00:30:35.810 Finally, we'd like to express our gratitude to the community. We often share snapshots of companies utilizing JRuby in unique ways, like NASA using it in their exploration efforts. There are many exciting use cases we can highlight!
00:31:11.680 Thank you all for your attention! If you have any questions, we're happy to take them now!