多次元配列の実行時間に関してはRuby>>Matlab>C

最近、Matlabの実行速度が遅いというエントリーを書きましたが、Matlabはプロトタイピングにはとても便利なツールです。そこそこの速度も出ますし。ただ、他の人にプログラムを使ってもらうときには、その人もMatlabを持っている必要があるのがネックになります。Matlabが無料ならそれほど問題にはならないのですが、Matlab実行環境はパソコン一台買えるほどの値段なので、なかなか趣味で買えるようなものではありません。

Matlab互換のOctaveは無料で手に入りますが、(ジャンルは違いますが)Rubyのほうが書籍も充実しているので、これからプログラミングを始める人に勧めやすい気がします。そこで、Matlabの強みである多次元配列の計算がRubyではどうなっているのか検索してみました。すると、そのものズバリの「Rubyによる多次元配列の実装方法について」という記事にあたりました。もともとRubyには多次元配列の機能はないので、自作する必要があるのだそうです。しかも、いくつか挙げられていた実装方法のベンチマークでは、かなり遅い様子。僕のマシンで実行してみると、

$ ruby foo.rb
DimByStd                  1.730 sec
DimByAry                  1.000 sec
DimByHashAry             12.350 sec
DimByHashPack             1.400 sec
DimByHashStr              1.850 sec

となりました。ほぼ同じ動作(30x30x30の3次元配列に値を代入し、中身を加算する、10回繰り返し)をするMファイルを作り、実行してみました。

tic;
N = 30;
for k=1:10
  A = zeros(N,N,N);
  for n1=1:N
    for n2=1:N
      for n3=1:N
        A(n1,n2,n3) = n1+n2+n3;
      end
    end
  end
  z = 0;
  for n1=1:N
    for n2=1:N
      for n3=1:N
        z = z + A(n1,n2,n3);
      end
    end
  end
end
toc;

結果、約0.010秒。多次元配列に関してはMatlabの圧勝です。同じものをC言語でも作ってみると、約0.005秒。実行時間ではRuby>>Matlab>Cとなりました。

id:yna1962さんが作成されたRuby版は僕が作ったMatlab版よりもだいぶ複雑な処理をしていますし、Rubyはもともと数値計算をメインに考えた言語じゃないので、言語そのものに多次元配列の機能が入っているもののほうが速いというのは当たり前と言えば当たり前です。あと、JITコンパイラが入っているMatlabとの直接比較は反則かも。jrubycとかでJITを有効にするとガツンと速くなる可能性もあります。

いずれにせよ、速度が必要なら、Rubyのコード可読性を犠牲にしてCやアセンブリで書くほうがいいんでしょう。適材適所。