Multithreaded processing with Ruby
Posted on May 4, 2015 by Fernando T
Ruby is a dynamic, reflective, object-oriented, general-purpose programming language. Ruby was influenced by Perl, Smalltalk, Eiffel, Ada, and Lisp. It supports multiple programming paradigms, including functional, object-oriented, and imperative.
As a scripting language, Ruby runs with an Interpreter. The official Ruby interpreter often referred to as the Matz’s Ruby Interpreter or MRI. This implementation is written in C and uses its own Ruby-specific virtual machine.
Many people claim that Ruby does not have the same performance compared to other languages. While this may be more or less true, we have to consider that much of the performance you get will depend on many factors, including the interpreter we are using.
JRuby
Besides the MRI, another of the interpreters available that supports the Ruby programming language is JRuby.
According to the official documentation, JRuby is a 100% Java implementation of the Ruby programming language. It is Ruby for the JVM.
JRuby is Ruby 2.2 compatible and supports Rails 4.
Disadvantage from JRuby:
JRuby cannot run native C extensions, however, but popular libraries have all generally been ported to Java Native Extensions. So, in general, we will find an alternative library for JRuby.
Which is faster: MRI Ruby or JRuby?
This depends, but we can can make do some benchmarking to try to answer
Example 1 with 5000 iterations:
1a) Benchmark results with Ruby MRI 2.2.1p85:
1b) Benchmark results with JRuby 1.7.19 (1.9.3p551):
We can see in the output, that in this case, Ruby MRI is more faster than the JRuby JVM.
But, what happen with a high load of data, e.g. with 50000000 iterations rather than 5000?
Example 2 with 50000000 iterations:
2a) Benchmark results with Ruby MRI 2.2.1p85:
2b) Benchmark results with JRuby 1.7.19 (1.9.3p551):
In the second example, we can see that the time is greatly reduced with JRuby and JVM.
Not bad, but what happens if we change our example with 3 Threads?
Example 3 with independent threads and joins:
3a) Benchmark results with Ruby MRI 2.2.1p85:
3b) Benchmark results with JRuby 1.7.19 (1.9.3p551):
Now we are able to see a big difference in the real time and total time. JRuby in this case is much faster.
Why is JRuby an improvement when compared with MRI?
The key is the number of concurrent threads running simultaneously.
MRI can have multiple threads, but run only one at a time, while JRuby, through the JVM can run several simultaneously, making it a more intense use of processing, allowing multiple runs, each on a separate CPU thread if we have the hardware for support it and if our application is thread safe.
We can verify using the top command:
MRI:
JRuby:
Where TH: Number of threads (total/running).
Conclusion
Each interpreter is best suited for a particular situation, but in case we need high processing power, besides reviewing the order of complexity of an algorithm, we can also try JRuby as an alternative to see if it improves the actual processing time of our application or API.
###References & more information: