RubyKaigi 2015参加レポート n = 1 #{n}日目""

こんにちは、料理サプリのサーバーサイド担当のnewuniverseです!

11月に島根県松江で行われた RubyWorld Conference 2015 に続き、東京で開催された RubyKaigi 2015 に参加してきました。

週末も含む3日間の長丁場でしたが、今回弊社はプラチナスポンサーということで、社員としてフルで参加してきました。当エントリでは1日目のレポートをお届けします。またスポンサーページで弊社の紹介文がRubyコードになっているのでお試しあれ!

RubyKaigi 2015

会場が築地市場の近くということもあり、寿司のテーマが強調されています。当日寿司が大盤振る舞いされたそうですが、列が長く諦めました...

Ruby3x3

RubyWorld Conferenceと同じくRubyKaigiもMatz氏のキーノートスピーチで幕を開けました。話のトピックは主にRuby 2.3.0 preview2のリリース発表とニューフィーチャー紹介、そしてRuby 3.0に向けた取り組みでした。

Ruby 2.3.0 preview2

では実際にrbenvで2.3.0を試してみましょう!

$ rbenv install -l
Available versions:
...
2.3.0-dev
...
$ rbenv install 2.3.0-preview2
$ rbenv shell 2.3.0-preview2

Magic comment

# frozen-string-literal: trueというmagic commentが追加され、いちいち全てのstringについて.freezeしなくて済むようになりました。

# test2.3.rb 下がmagic comment
# frozen-string-literal: true
a = "foo"
puts a.frozen? #=> true 
a.replace("bar") #=> can't modify frozen String (RuntimeError)
b = "bar"
b.replace("foo")
puts a, b

dig

Array#digHash#digで深くネストされたオブジェクトを簡単に辿れるように、存在しなければnilが返るようになります。興味深いのはArrayHashを混用しても問題ないということ。これは非常に便利です!

# test2.3.rb
deep_nest = [
  {
    key1: ["a", "b", "c"],
    key2: { d: "d", e: "e" }
  },
  [
    {
      key3: "f",
      key4: "g"
    },
    "h"
  ]
]
p deep_nest.dig(0, :key1, 1) # deep_nest[0][:key1][1]と同じで=>"b"
p deep_nest.dig(1, 0, :key4) #=>"g"
p deep_nest.dig(1, 0, :key5) #=>nil

Safe navigation operator

lonely operatorことsafe navigation operatorの&.、足を組んで座り、ぼっちでボールを遊んでるように見えますw

Swiftなどでは?.で採用されており、メソッドチェーン上の nil check の記述がだいぶ楽になり、すっきり書けます。

u = User.first
u&.name&.first
u && u.name && u.name.first #上の記述と同義

Hash comparisons(包含関係)

Hash間の包含関係の真偽値を取得できるようになりました。

hash_outer = {
  a: "a",
  b: "b",
  c: "c"
}
hash_inner = {
  a: "a",
  b: "b"
}
p hash_outer > hash_inner #=> true

More

他にも以下のような機能も追加されています。

  • Enumerable#grep_v
  • Hash#values_at, Hash#to_proc
  • Numeric#positive?/negative?
  • did-you-mean gemのバンドル

Ruby 3.0

Matz氏は3.0の課題で着手したい課題を以下に挙げています。

  • multi cores concurrency
  • code scalability
  • data scalability

その根源にはまだRubyの処理が比較的に遅い理由があり、毎年5-10%のパフォーマンスアップをしているが、Ruby3ではRuby2より3倍速く1)但し2.0と3.0の比較でなるようにするとMatz氏は公言しています。
セクションタイトルのRuby3x3はこれに由来しています。またIBM J9がRubyに対応するとの発表もありました。

Compiling Ruby scripts

Ruby3x3が発表されたからでしょうか、初日は特にRubyを速くする施策に関するセッションが多く見られました。Koichi Sasada氏のセッション内容を紹介します。Sasada氏はYARV (Yet Another Ruby VM)の開発者であり、YARVは現在Matz's Ruby Interpreter(MRI)に組み込まれています。

バイトコードインタプリタとして実装されており、従前の処理系ではevalルーチンが直接読み込んでいたRubyプログラムの構文木を、バイトコ-ドにコンパイルし、evalを置き換えた仮想計算機上で実行する。

Slack for iOS Upload

上図のようにMRIではRubyスクリプトをパースし、中間言語のバイトコードinstruction sequences(iSeq)にコンパイルして実行処理へと続きます。いわゆる実行時(JIT)コンパイラであり、処理速度がコンパイルによるオーバーヘッドに大きく影響されます。また簡単なRailsアプリでも全体の約15%のメモリがiSeqによって消費されているデータも提示されていました。

そこでSasada氏は事前にRubyスクリプトからiSeqを生成し、更にバイナリにシリアライズする方法を提唱しています。いわゆる事前(AOT)コンパイラです。このようにすることで、必要なときバイナリを読み込み、デシリアライズしてiSeqに戻し実行処理に移れ、実行時のコンパイルが不要になります。これは遅延読み込みを適用したりすることによりメモリ消費を抑えることも期待されます。

具体的なシリアライズ・デシリアライズ方法などは全ては記憶できませんでしたが、今後様々な手法と工夫によってRubyが益々高速化していくでしょう。今後も動向に目が離せないのはもちろん、Ruby 3.0が早く世にでることを期待します。

脚注

脚注
1 但し2.0と3.0の比較で