Rubyは思ったより速いかもしれないとの指摘

[PR]記事内のアフィリエイトリンクから収入を得る場合があります
  • URLをコピーしました!

Pexels photo 399636

国産プログラミング言語「Ruby」は、インタプリタ型のプログラミング言語であるため、「処理速度が遅そう」というイメージを持つ開発者の方もいるかもしれません。

しかし今回、Rubyで書かれたプログラムも工夫次第で十分高速に操作することを、John Hawthorn氏はブログ記事「Ruby might be faster than you think」で指摘し、Hacker NewsRedditで注目を集めています。

同氏が例として掲載しているのは、crystalrubyと呼ばれる、Rubyの中からCrystalを呼び出すためのgemのサンプルプログラムです。

CrystalはRubyに似た構文を採用した静的型付けプログラミング言語です。

フィボナッチ数を計算するプログラムで、Pure Ruby版のfib_rbとCrystalのコードを呼び出すfib_crの実行速度を比較しています。

require 'crystalruby'
require 'benchmark'

module Fibonnaci
  crystalize [n: :int32] => :int32
  def fib_cr(n)
    a = 0
    b = 1
    n.times { a, b = b, a + b }
    a
  end

  module_function

  def fib_rb(n)
    a = 0
    b = 1
    n.times { a, b = b, a + b }
    a
  end
end

puts(Benchmark.realtime { 1_000_000.times { Fibonnaci.fib_rb(30) } })
puts(Benchmark.realtime { 1_000_000.times { Fibonnaci.fib_cr(30) } })

最初は以下のように、Ruby版が大幅に遅い結果となりました。

$ ruby test.rb
2.113752398872748
0.6535678738728166

しかし同氏は、Rubyのブロックが配列を生成することに着目し、これを抑制することで速度を改善します(n.times{}の最後でnilを返しています)。

def fib_rb(n)
  a = 0
  b = 1
  n.times { a, b = b, a + b; nil }
  a
end

さらにブロックを普通のループに書き換え、最近のRubyで利用可能なYJITを使用することでPure Ruby版がCrystal版の速度を上回ることを示しています。

def fib_rb(n)
  a = 0
  b = 1
  while n > 0
    a, b = b, a + b
    n -= 1
  end
  a
end

ruby --yjitで実行します。

$ ruby --yjit test.rb
0.10502525512129068
0.5002881051041186

最終的にCrystal版より5倍高速度で、オリジナル版のRubyより20倍速い結果がでています。

同氏は、FFI(Foreign function interface)か、それに類するものによるコストが影響している可能性があるが、Rubyのコードに少し手を加えるだけで、大きく速度が向上するのは注目に値するとまとめています。

個人的には最終的な勝敗よりも、ブロックをループに展開することで速度が向上するところが興味深いと思いました。Rubyプログラムのパフォーマンスを改良したい場合に参考になるテクニックかもしれません。

タイトル Ruby
公式サイト http://www.ruby-lang.org/ja/
ソフトアンテナ https://softantenna.com/softwares/1964-ruby
説明 オブジェクト指向スクリプト言語。
タイトル Crystal
公式サイト https://crystal-lang.org/
ソフトアンテナ https://softantenna.com/softwares/6966-crystal
説明 Ruby風のシンタックス&静的な型を持つプログラミング言語
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次