05 Jan 2016
In RubyKaigi2015 held at Tokyo last month, Koichi Sasada has announced the experimental release of bytecode cache in Ruby2.3. You are likely to be able to test this experimental feature as follows for example, by verifying bytecode cache(.yarb file) is generated successfully.
$ ruby -v ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux] $ ls /usr/local/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5/lib/ active_support active_support.rb $ export RUBYOPT='-ryomikomu' && export YOMIKOMU_AUTO_COMPILE='true' $ rails -v Rails 4.2.5 $ ls /usr/local/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5/lib/ active_support active_support.rb active_support.rb.yarb
It may look a bit magical why VM-level bytecode cache is enabled only by requiring 'yomikomu' rubygem. Koichi described about this at his ticket.
The key interface is RubyVM::InstructionSequence.load_iseq(fname). When MRI try to load any script named fname, then call this method with fname if defined. The return value is an ISeq object, then MRI use this ISeq object instead of parsing/compiling fname file.
In short, 'yomikomu' rubygem defines RubyVM::InstructionSequence.load_iseq while VM(MRI) checks if #load_iseq method is defined at its boot timing and thus VM decides cache is enabled or not. We can find corresponding lines of code in ruby/iseq.c.
Here is a quick benchmark result of current bytecode cache implementation. I used 'bundle version' command with benchmark-ips on Ubuntu machine. Source
$ ruby measure.rb Comparison: yomikomu(fs): 5.0 i/s yomikomanai: 3.6 i/s - 1.40x slower
It may vary depending on what command is used but from my quick check bundler was the most optimized in terms of speed. For more information including more benchmark score, please refer Koichi's presentation material presented at RubyKaigi2015 as well as his speech video.
Now is the time to deep-dive for speeding up MRI towards Ruby3.0!
@remore is a software engineer, weekend contrabassist, and occasional public speaker. Read more