高速&省メモリ perl-xs版 split モジュール
大量の csv ファイルを読み込んで処理をするとき、カンマやタブ区切りのレコードを split や正規表現を使って文字列を分割して配列に入れて処理・・・なんて事は良くやります。mysql 等のデータベースに入っているデータなら速度的に問題が発生することは少ないのですが、どうしても csv のまま処理をしなければならない場合、文字列の分割のコストがバカになりません。
perl の split はかなり優秀で正規表現で分割するよりも高速に文字列を分割することが可能です。しかしながら、split でさえ用件によっては遅い場合もあります。実際、1 レコードあたり 300 カラム程度のデータが 20 万件ほど存在する場合、split で分割して配列に格納するコストが Pentium-4 2.8G + メモリ 2G ですら、30 〜 40 秒ほどかかってしまいます。
そこで、僅かながらではありますが、より高速な XS モジュールを書きました。約 3 割程度の高速化が見込めるだけでなく、極力省メモリ仕様で記述したので少ないメモリでも効率的に文字列を分割できます。(多分・・・)
≫スクリプトはこちら(DrkSplitFast.tar.gz)
<動作環境>
gcc 等の C コンパイラが使用可能な環境。(Linuxでしか動作確認してませんが...)
(1)まずはサーバ内の適当なところへFTP下さい。
(2)いつもの install 作業
tar xvfz DrkSplitFast.tar.gz
cd DrkSplitFast
perl Makefile.PL
make
make install
(3)ベンチマーク
perl-split とのベンチマークをとりたい方は、 t/bench.pl を実行下さい。下記、ウチの環境の結果。
perl split[50000 x 10]LOOP TIME=1
xs split[50000 x 10]LOOP TIME=0
make test-data
perl split[50000 x 50]LOOP TIME=2
xs split[50000 x 50]LOOP TIME=1
make test-data
perl split[50000 x 100]LOOP TIME=4
xs split[50000 x 100]LOOP TIME=3
make test-data
perl split[50000 x 200]LOOP TIME=8
xs split[50000 x 200]LOOP TIME=6
以上で、perl から Drk::SplitFast が使用可能になります。
<Drk::SplitFastのメソッド>
- $xs = Drk::SplitFast->new();
コンストラクタ。引数なし。 - $array_ref = $xs->split("文字列", "半角1文字のデリミタ記号");
分割後の結果が配列へのリファレンスで返ってきます。
コメントやシェアをお願いします!