RubyKaigi 2017 Day 1
27 Sep 2017This is my third RubyKaigi and my first in Hiroshima. This is also the first time where I’m not speaking (though I am on the waitlist).
Getting to Hiroshima was tough due to a typhoon that went across the island. Some people were stuck on the Shinkansen (bullet train) for over 8 hours trying to make the journey from Tokyo to Hiroshima.
My flight was delayed and I ended up getting a hotel for the night in Tokyo. The room was small but nice and it was good to kick off my shoes after a long flight.
The next morning I made my way to RubyKaigi, but sadly not in time to hear the first talk from Nobu. He is the “patch monster” with the most commits to Ruby. He is also a Heroku employee!
RubyKaigi represents the unique opportunity to hear Japanese Ruby committers present in their native tongue. As a result I tried to go to as many Japanese presentations as possible. While they’re all recorded, the translations are not uploaded to youtube.
After getting to the venue here’s my first day at RubyKaigi.
Koichi Sasada: “Fiber in the 10th Year”
I saw a talk by Koichi about 10 years of Fiber development. Contrary to the name, it’s got nothing to do with cereal. Fiber is a “lightweight” thread. The main difference between a fiber and a thread is that a thread will be auto-scheduled to run and will also context switch when it encounters IO. A fiber must be manually scheduled by a programmer.
The talk was in Japanese and I used a translator earpiece, so I may have missed some points. It sounds like the name and structure Fiber is not a common one. The name was borrowed with permission from another implementation, and since then, other languages have implemented Fibers similar to Ruby. So it seems that Ruby made the idea of a Fiber more popular.
Koichi mentioned that he spent 2-3 months working on performance improvements to the current Fiber implementation recently, and while he saw only modest speed increases he is hoping the work will help with future work on “Guilds”, which are is a primitive that will allow multiple copies of Ruby code to execute simultaneously.
Another interesting thing he mentioned was a proposal for an “Auto Fiber” (proposed by Eric Wong), this is a fiber but it auto-context switches when it encounters IO. The difference between an “Auto Fiber” and a thread is that threads can be pre-empted. That is to say, if the thread is in the middle of doing some task that is not IO related, it can be paused while another thread runs. This happens in Ruby on a timer so each thread gets a fair share of CPU time. With an “auto fiber” the only time it would yield execution is while performing IO or if the execution was manually yielded. While synchronization around data would still be required with an Auto Fiber, there is less required since the fiber will only yield on IO. I think the main benefit though is that with threads there is a cost every time a thread must be context switched. With a fiber since it only yields on IO, it will not context switch as much and that context switch time can be saved.
Noah Gibbs: “How Close is Ruby 3x3 for Production Web Apps”
After Koichi, I saw Noah Gibbs give a talk on the Ruby Bench project. He talked a lot about testing methodology and results with lots of graphs. One interesting thing he pointed out was that the performance characteristics around Ruby related to “warmup time” seemed to be consistently linear for all versions of Ruby. What that means is that your Rails app will serve the 1000th request slightly faster than the 1st request because the VM has been “warmed up”. Noah pointed out that in other languages while they get faster over time, they also need much longer to warm up for that speed to be realized. Ruby is getting faster, but it does not require exponentially more warm-up time.
Noah has written a lot about his work on appfolio’s engineering blog.
SHIBATA Hiroshi: “Gemification for Ruby 2.5/3.0”
Once I was out of Noah’s talk I went to SHIBATA’s talk on the work going into Gemifying the standard lib. The idea is that by having the concept of an “internal gem”, we can get the benefits of having a library ship with the default version of Ruby like a standard library. We also get the benefits of a gem that can be upgraded and released in rapid succession instead of relying on the Ruby release cycle.
Internally you can check if a library is a “default gem”.
require 'openssl'
Gem.loaded_specs["openssl"].default_gem?
# => true
There are a number of libraries that have already been converted to “default gems”.
The biggest downside I can tell is that the process requires more work from maintainers since they have to update a separate repo in addition to the code in the Ruby repository. For things like open SSL where it may be critical to getting a patch as soon as possible, it makes sense to have it installable as a default gem.
In Ruby 2.5 Bundler is supposed to be moved to a “default gem” so that you don’t run into this problem after upgrading or installing a new Ruby version:
$ bundle install
-bash: bundle: command not found
Shizuo Fujita: “How to optimize Ruby internal”
One of my favorite talks of the day came after the afternoon break. One of the sponsors in the sponsor hall was passing out coffee, so maybe there’s a correlation there.
The talk was by Shizuo Fujita who is working in optimizing Ruby internals and he spoke about the general patterns for optimizing code. It isn’t so different from optimizing Ruby code, mostly avoiding allocations to save time. He shared his benchmarking methodologies using a Mac tool called iprofiler
. For example, if you have a script called scratch.rb
and you are using Ruby 2.4.2 on your system you can profile it like this:
$ iprofiler -timeprofiler /Users/schneems/.rubies/ruby-2.4.2/bin/ruby ./scratch.rb
iprofiler: Preparing recording resources
iprofiler: Profiling process 29245 (ruby) for 10 seconds
iprofiler: Timer expired. Ending recording.
iprofiler: Saving session...
iprofiler: Session saved at /private/tmp/ruby.dtps
Once you have the dtps
file you can open it in the instruments
app.
$ open /private/tmp/ruby.dtps
He spoke about a few performance improvements. One was speeding up Hash#merge
. Here’s the commit https://github.com/ruby/ruby/commit/9cd66d7022aa2b8aff719a26c594efc9c3797ec1.
He switched out a call from rb_obj_dup
to rb_hash_dup
. This avoids a call lookup and the hash dup method looks like it does less work.
Overall that patch made Hash#merge
50-60% faster.
He shared some examples of other optimizations he would like to make. I think it will be interesting to see future patches.
Ruby Committers vs the World
After so many talks in Japanese (via a translator) I needed a bit of a break so I sat out for the last session and came back for “Ruby Committers vs the World”. This is where the committers sit on stage and answer audience questions.
There was some interesting discussion around adding static typing or optional static typing. There was also some discussion about being able to assign variables from left to right instead of right to left. I think they decided that you could already do this since you can write your own method to achieve this goal. But they did talk about it for a really long time.
After that, there was a party with a giant barrel of sake which we drank out of cedar boxes. It was pretty great.
While it’s exhausting to listen to translators all day it’s really worth it to hear a perspective that I won’t get anywhere else in the world. RubyKaigi is the largest single group of Ruby contributors and home of some extremely technical talks. I always leave with my head hurting a bit but much smarter. The first day of this year is no exception.
If you’re interested in going I wrote a short post on my observations of how Kaigi is different from other conferences you may have attended. You can read my Gajin Guide to RubyKaigi.
I was going to write up notes on the other days but A) my jetlag started kicking in and B) All the videos for RubyKaigi are now online (click on the talk title).