何故か、Facebookで@shinyorkeさんとJapan.Rの話をしてたら、@0kayuさんに補足されてしまったので、LT発表してきました。
MeCab.jlの紹介と、R,Ruby,Juliaでのベンチマークについて話しました。
ベンチマーク結果を見ると、gcを切ったらRにはなんとかかっています。
ベンチマークに使用したコードはこちら https://gist.github.com/chezou/1f947423c6655c266e0a
各言語のversionはこんな感じです。
$ ruby -v ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin13.0] $ julia --version julia version 0.4.0-dev+1752 $ r --version R version 3.1.2 (2014-10-31) -- "Pumpkin Helmet" Copyright (C) 2014 The R Foundation for Statistical Computing Platform: x86_64-apple-darwin13.4.0 (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under the terms of the GNU General Public License versions 2 or 3. For more information about these matters see http://www.gnu.org/licenses/.
やる前はRに対して圧勝!とかならないかなぁとか思っていたのですが、そもそもMeCabをバインディングしてるだけじゃん、と気づいた時には甘かった。 敵は、Rではなかったのです。Cだったのです...。
共有ライブラリを配布して、それをRから呼べるようにしているだけとは恐れ入りました。 RMeCabは、まさか頻度カウントをするための関数まであるとは思ってもみなかったのですが、基本的に遅くなる処理はCにまかせてしまうというのは戦略的には合理的ですね。
おまけ
会場ではきちんと言えなかったのですが、Juliaのバインディングをする上でのPros/Consはこんな感じです
Rubyに対して遅いのは、ちょっと検証してみます。
特に「Cを書くことなく」という点は素晴らしく、 MeCabのnodeの構造体に対応するtypeを作れば、それでcastしてくれてJuliaから扱えるようになります。
mecab.hからCのコードを抜粋
struct mecab_node_t { struct mecab_node_t *prev; struct mecab_node_t *next; struct mecab_node_t *enext; struct mecab_node_t *bnext; struct mecab_path_t *rpath; struct mecab_path_t *lpath; const char *surface; const char *feature; unsigned int id; unsigned short length; unsigned short rlength; unsigned short rcAttr; unsigned short lcAttr; unsigned short posid; unsigned char char_type; unsigned char stat; unsigned char isbest; float alpha; float beta; float prob; short wcost; long cost; };
対応するMeCab.jlのコード
type MecabRawNode prev::Ptr{MecabRawNode} next::Ptr{MecabRawNode} enext::Ptr{MecabRawNode} bnext::Ptr{MecabRawNode} rpath::Ptr{Void} lpath::Ptr{Void} surface::Ptr{Uint8} feature::Ptr{Uint8} id::Cint length::Cushort rlength::Cushort rcAttr::Cushort lcAttr::Cushort posid::Cushort char_type::Cuchar stat::Cuchar isbest::Cuchar alpha::Cfloat beta::Cfloat prob::Cfloat wcost::Cshort cost::Clong end
mecab_node_path_t
は使っていないので捨てています。
Cの場合、headerに構造体を先に宣言すれば、お互いが依存する構造体を記述できますが、Juliaの場合はそれができないためPtr{Void}
で受けています。