Released in Xmas 2020, Ruby 3 is a big release.
2020 might be a year of despair, pain and agony, but for the Ruby developers celebration came early in the form of a newly released Ruby programming language. They couldn’t keep calm. Why should they, afterall, it had been in the works for a really long time.
Ruby 3.0 was released. The bigger new features are static analysis and concurrency features. In our blog, we will focus on some of the highlights of this release.
How is Ruby 3.0 Different?
It brings us to the question on every Ruby on Rails developers’s mind all around the world - how different Ruby 3.0 is from its earlier versions!
The main USP of Ruby 3 is it’s faster than Ruby 2. The Ruby team has been working on bringing new and improved features in the latest versions. However, they have given more importance on ensuring the performance and maintenance of backward compatibility. The recent additions of new features like Ractor, scheduler, Type checking and some improvements to the present paradigms like fibers, memory, performance, static analysis and concurrency has been a game changer.
Ruby 3 major updates
The major three goals of Ruby 3 stands: ensuring correctness, faster and having better concurrency.
Let’s talk about the performance.
Ruby 3 performance
Ruby wasn’t designed to be faster. Had it been designed as faster, it would have turned up something else. One of the main focuses for Ruby 3 was its performance. As you know Ruby language gets a performance boost, it absolutely helps apps to become scalable and run faster.
Ruby’s performance is measured by two parameters: It’s Memory and CPU.
CPU optimization: Few enhancements in Ruby internals have been made to increase the speed. First introduced in Ruby 2.6, Ruby MJIT compiler has been optimized by the Ruby team using previous versions. Thus, Ruby 3 MJIT has better security and enhances web application performance to a greater extent.
MJIT implementation is quite different from the usual JITs. When methods are called repeatedly for example 9k times, MJIT will pick such methods. It will be compiled into native code and put into a queue. Later on, MJIT can get the queue and convert them into native code.
Memory optimization: Ruby 3 has an functionality- enhanced garbage collector. It’s more like the python’s buffer alike API which helps in memory utilization. Since the release of Ruby 1.8, Ruby has constantly evolved the algorithms of Garbage Collection.
- Automatic Garbage Compaction: This is the latest version of garbage collection. Introduced in Ruby 2.7, the process was manual. In version 3.0, it has been fully automatic. The compactor is also cited properly to ensure better memory utilization.
- Objects Grouping: Garbage Compactor passes objects in heap. All the objects are distributed in a group at a single place in memory. Later on, this memory can be reused by heavier objects.
Let’s talk about Parallelism and Concurrency in the newly released Ruby 3.
Parallelism and Concurrency in Ruby 3
So, what is Concurrency? Concurrency is a vital aspect of any programming language. In Ruby 3, it becomes a lot easier to build applications if concurrency is a major focus. However, several features and improvements related to Concurrency such as Ractor have been put on in Ruby 3.
The Global Interpreter Lock (GVL) feature of Ruby had stopped it from being used by developers to operate multiple cores at the same time. To make this happen, a new concurrency has been established, called Ractor. Ractor is more like an actor-model like concurrent abstraction used to perform parallel execution without any thread safety issues.
The Ractor authorizes threads in other Ractors to calculate at the same time. Each Ractor has at least one thread, which further contains several fibers. In a Ractor, only a single thread is permitted to function at a time. You can further see a simple example in the Ractor docs on how passage of message works with Ractors.