NArrayっぽいやつをいろいろ試しました
はじめに
「MF / Numo::NArray を試してみる」を拝見し、NumRu::NArrayもあると思ったので試してみました。ほぼ真似です。すみません。
実行環境は以下の通りです。
- MacBook Pro (Late 2013)
- OS X El Capitan 10.11.5
- rbenvで入れたRuby 2.3.1
NArray 0.6.1.2
他のNArrayっぽいやつに多大な影響を与えたと思われる旧バージョンです。これのおかげで、いろんなデータ解析が捗りました。作者様ありがとうございます。
require 'narray' require 'benchmark' SIZE = 16384 Benchmark.bmbm do |x| x.report do a = NArray.float(SIZE, SIZE).random b = NArray.float(SIZE, SIZE).random c = a * b end end
実行結果
benchmark_narray.rb:10:in `float': allocation size is too large (ArgumentError) from benchmark_narray.rb:10:in `block (2 levels) in <main>'
旧NArrayではこんなに大きいサイズは扱えないようです。
NumRu::NArray 1.0.3
NumRu::NArrayはNArrayにbig memory supportを加えたものだそうです。
require 'numru/narray' require 'benchmark' # ENV['OMP_NUM_THREADS'] = '4' include NumRu SIZE = 16384 Benchmark.bmbm do |x| x.report do a = NArray.float(SIZE, SIZE).random b = NArray.float(SIZE, SIZE).random c = a * b end end
実行結果
user system total real 9.370000 7.030000 16.400000 ( 20.239738)
NArrayではエラーになったサイズの計算ができました。
Numo::NArray 0.9.0.1
Numo::NArrayは、期待の新NArrayです。GSLとのインタフェースもあるようです。すばらしいです。
require 'numo/narray' require 'benchmark' include Numo SIZE = 16384 Benchmark.bmbm do |x| x.report do a = DFloat.new(SIZE, SIZE).rand b = DFloat.new(SIZE, SIZE).rand c = a * b end end
実行結果
user system total real 7.840000 2.570000 10.410000 ( 12.739366)
おお、NumRu::NArrayより速い。
NMatrix 0.2.1
NMatrixは、Rubyでscientific computingをやろうというSciRubyのfast numerical linear algebra libraryです。以前はNArrayと同時にはインストールできなかったのですが、require 'nmatrix/nmatrix'
とすれば使えるようになったようです。
require 'nmatrix/nmatrix' require 'benchmark' SIZE = 16384 Benchmark.bmbm do |x| x.report do a = NMatrix.random([SIZE, SIZE]) b = NMatrix.random([SIZE, SIZE]) c = a * b end end
実行結果
user system total real 129.120000 6.300000 135.420000 (137.681446)
遅いです。
GSL::Matrix 1.16.0.6
GSL::Matrixは、GSLのRubyバインディングで使えます。
require 'gsl' require 'benchmark' include GSL SIZE = 16384 Benchmark.bmbm do |x| x.report do r = Rng.alloc a = Matrix.alloc(SIZE, SIZE).map { r.uniform } b = Matrix.alloc(SIZE, SIZE).map { r.uniform } c = a.mul_elements(b) end end
実行結果
user system total real 54.000000 6.220000 60.220000 ( 62.904272)
このコードでは乱数を生成してセットする部分にワンクッションあるのでどうしても遅くなります。でも、NMatrixよりは速いです。
まとめ
今回は、Numo::NArrayが最も速いという結果になりました。