On Blahfe

RubyのCSVパースをPyCallで実行する(ベンチマーク)

blog/backendrubybenchmarkpycall
thumbnail

先日RubyからPythonにアクセスできるPyCallというライブラリの存在を知り、ぜひともベンチマークを取りたいと思った次第です。現状RubyのCSVの読み込みに不満を持っており、そこをどうにか解消したいと考えています。

PROBLEM

  • 大量のCSVを読み込む際、毎回時間がかかる

SOLUTION

というわけで、「Dalibor Nasevicのベンチマーク記事」にPyCallのベンチマークをくわえて比較してみることにしました。記事では下記の通り CSV.foreach が速いとの結論でした。

kind_of_parse time (real) memory (MB)
1. CSV.read 39.13 866.6
2. CSV.parse 36.16 936.87
3. line by line from String Object 23.39 73.42
4. line by line from IO Object 24.55 0.0
5. CSV.foreach 24.04 0.0

PyCallのベンチマーク

それでは、PyCallのベンチマークを計りましょう。コードは下記のようになります。

ruby
require_relative './helpers'
require 'pycall/import'
include PyCall::Import
pyimport :pandas, as: :pd

print_memory_usage do
  print_time_spent do
    csv = pd.read_csv.('data.csv')
    sum = csv['id'].sum.()
    puts "Sum: #{sum}"
  end
end

PyCallは pyenv との相性が悪いのでSystemインストールしたPythonでたたきます。

sh
$ PYTHON=/usr/bin/python3.4 ruby parse_6_pycall.rb
Sum: 499999500000
Time: 1.49
Memory: 54.99 MB

結果

kind_of_parse time (real) memory (MB)
1. CSV.read 39.13 866.6
2. CSV.parse 36.16 936.87
3. line by line from String Object 23.39 73.42
4. line by line from IO Object 24.55 0.0
5. CSV.foreach 24.04 0.0
6. PyCall 1.49 54.99

はい、結果が出ました。Daliborのベンチマーク記事で一番速かった CSV.foreach より16倍の実行速度となりました。

WRAPUP

PyCallのオブジェクトが PyObjectとActiveRecordと相性が悪そうなのと、PythonとRuby双方のメモリー管理が運用を難しくすることから、安易に本番環境のRailsに導入するのは厳しいと思います。

ただし、実行回数が限定されたスクリプトなら積極的に使って良いでしょう。

nabinno
Emacsianでアート好き、ランニング好きな@nabinnoが書いています
GitHub / X / LinkedIn / ネクイノ
blog/market

今後の成長分野:新たなテクノロジーの展望

テクノロジーの進化は、絶え間ない変化の中で私たちの日常を塗り替えてきました。時には経済的な危機が、新たな可能性を切り拓く契機となることもあります。そこで、過去のリセッション期に生まれたテクノロジーの足

market-trendrecession
blog/organization

ATKerneyの課題解決パターンの魅力的な探求

ATKerneyの課題解決パターン は、課題の本質を見極め、効果的な戦略的構造化を通じて解決策を導き出す手法にフォーカスしています。この冒険の旅は、解決者と協力者たちが心を一つにし、課題に立ち向かう様

problem-solvingatkerney
blog/market

就職氷河期とは何だったのか

私はいわゆる就職氷河期世代です。周囲から時折漏れ聞こえる不平のような言葉がありますが、それを単なる不平として片付けるのはもったいない気がします。できれば、その中に新しい視点を見つけ、次のチャンスへ繋げ

labor-economicsrecessionemployment-ice-age