アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

Ruby 2.7がリリースされましたね!

morishitaです。

年末もだいぶ押し迫ってきました。
当社も今日が2019年の仕事納めです。

最近、仕事でRubyを書いていない私ですが、今年の最後はRubyの話題で締めくくろうと思います。

Ruby 2.7 リリース !

今年も年末恒例のRubyの新バージョンがリリースされましたね。

www.ruby-lang.org

次のような新機能、改善が含まれているようです。

  • Pattern Matching
  • REPL improvement
  • Compaction GC
  • 開始値省略範囲式
  • JITコンパイラ
  • メソッドキャッシュの改善
  • etc.

Pattern Matching なんかは気になる新機能ですね。
APIを叩いて、レスポンスのJSONの中身によって処理を分岐する場合などに便利そうなので使ってみたいです。

REPLのマルチライン対応も開発時に重宝するのではないでしょうか。

さて、以前Rubocop Performance の速度比較について書きました。

tech.actindi.net

その中で、String、Array、Hashについてバージョンごとの生成速度の比較を行いました。 当時、Ruby 2.7 はまだ preview1 だったのですが、 Ruby 2.7.0 が正式リリースされたので改めて計測してみました。

計測について

計測には BenchmarkDriver を利用しました。

次のRubyバージョンで計測しました1

  • 2.3.8
  • 2.4.9
  • 2.5.7
  • 2.6.5
  • 2.7.0

結果は秒あたりの実行回数 ips (Iteration per second = i/s)で示します。
各結果ともbenchmark_driver-output-gruffによるグラフで示します。グラフが長いほうが高速ということになります。

また、結果の値自体は計測環境の性能により変わります。
なので、バージョン間の差に着目してください。

では順に見ていきます。

計測結果

プログラム中でよく作成する次の3つのリテラル生成の速度を比べます。

  • String
  • Array
  • Hash

String

まずはストリング。 次のコードで計測しました。

require 'benchmark_driver'

output = :gruff
versions = ['2.3.8', '2.4.9', '2.5.7', '2.6.5', '2.7.0']

Benchmark.driver(output: output) do |x|
  x.rbenv *versions

  x.prelude <<~RUBY
    def string_literal
      'string literal'
    end
  RUBY

  x.report %{ string_literal }
end

結果は次の通り。

f:id:HeRo:20191227085640p:plain
ストリング リテラルの生成

preview1 でも Ruby 2.7 は遅くなっていましたが、リリース版も変わらなかったようです。

Array

続いて配列です。
次のコードで計測しました。

require 'benchmark_driver'

output = :gruff
versions = ['2.3.8', '2.4.9', '2.5.7', '2.6.5', '2.7.0']

Benchmark.driver(output: output) do |x|
  x.rbenv *versions

  x.prelude <<~RUBY
    def array_literal
      [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
    end
  RUBY

  x.report %{ array_literal }
end

結果は次のとおりです。

f:id:HeRo:20191227085716p:plain
配列リテラル生成

Ruby 2.6 で劇的に速度アップしていますが、Ruby 2.7では少し遅くなったようです。

Hash

最後はハッシュです。
計測コードは次のとおりです。

require 'benchmark_driver'

output = :gruff
versions = ['2.3.8', '2.4.9', '2.5.7', '2.6.5', '2.7.0']

Benchmark.driver(output: output) do |x|
  x.rbenv *versions

  x.prelude <<~RUBY
    def hash_literal
      { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 0 }
    end
  RUBY

  x.report %{ hash_literal }
end

結果は次の通り。

f:id:HeRo:20191227085746p:plain
ハッシュリテラル生成

バージョンが大きいほど速くなってますね。
これはRuby 2.7が最速です。preview1 のときより Ruby 2.6 との差が広がったように思います。

まとめ

結果的には preview1 とあんまり変わらなかったです。

こんな小さなプログラムでは Ruby 2.7 のパフォーマンスチューニングの成果を確認することはできないのかな。
でも、Rails のようにずっと稼働し続け、もっと大きなプログラムではパフォーマンスアップが期待できるのかなー。

来年はいよいよ Ruby 3 のリリースが予定されています。
Ruby 2.7 はその準備となるバージョンのようなのでアップデートを計画しないとなー。

最後に

アクトインディではエンジニアを募集しています。 actindi.net

では、皆さん良いお年を。


  1. Ruby 2.7 以外も最新バージョンにアップデートしています。