Text::MeCab を x86_64 環境でインストールする方法

mecab 作者の taku さんが記事に書いているように

DMAKI氏による MeCab の Perl モジュールが CPANにアップロードされたようです。SWIG で生成されたものより高速に動作するようです。こんなに差が出るとは正直驚きです。 MeCab::Node の iterator をまわして要素を取りだす処理は、SWIG の場合 tie hash になったり、正直遅いと想像していたのですが、お見事です。

mecab 標準の mecab-perl より高速とのことで、モジュールの安定性を待っている間にすっかり忘れてしまった Text::MeCab ですが、突然思い出したので使ってみようかと思いインストールしてみたところ、make test にてエラー。

う〜ん・・・たぶん x86_64 環境だからだろうと推測し情報集め。

- スポンサーリンク -

取りあえずでているエラーはこんな感じ。エラーを書いても意味がないけど、同じ現象になった方が検索でココに辿り着くようにとの意味で。

PERL_DL_NONLAZY=1 /usr/local/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/01-sanity..................
# Failed test 'use Text::MeCab;'
# in t/01-sanity.t at line 7.
# Tried to use 'Text::MeCab'.
# Error: Can't load '/root/.cpan/build/Text-MeCab-0.15/blib/arch/auto/Text/MeCab/MeCab.so' for module Text::MeCab: /root/.cpan/build/Text-MeCab-0.15/blib/arch/auto/Text/MeCab/MeCab.so: u
ndefined symbol: _ZSt2wsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_ at /usr/local/lib/perl5/5.8.7/x86_64-linux-thread-multi/DynaLoader.pm line 230.
# at /usr/local/lib/perl5/5.8.7/x86_64-linux-thread-multi/XSLoader.pm line 26
# BEGIN failed--compilation aborted at t/01-sanity.t line 7.
# Compilation failed in require at (eval 3) line 2.
# BEGIN failed--compilation aborted at (eval 3) line 2.
Bareword "MECAB_NOR_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 11.
Bareword "MECAB_UNK_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 12.
Bareword "MECAB_BOS_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 13.
Bareword "MECAB_EOS_NODE" not allowed while "strict subs" in use at t/01-sanity.t line 14.
Execution of t/01-sanity.t aborted due to compilation errors.
# Looks like you failed 1 test of 1.
# Looks like your test died just after 1.
t/01-sanity..................dubious
Test returned status 255 (wstat 65280, 0xff00)
DIED. FAILED test 1
Failed 1/1 tests, 0.00% okay

さて、解決方法です。Makefile.PL を以下のように編集。赤い部分が追記部分です。

WriteMakefile
(
    'DISTNAME'     => 'Text-MeCab',
    'NAME'         => 'Text::MeCab',
    'VERSION_FROM' => 'lib/Text/MeCab.pm',
    'PREREQ_PM'    => {},
    'INSTALLDIRS'  => 'site',
    'LIBS'         => [ split(/\s+/, $result->{libs}) ],
    'CCFLAGS'      => $result->{cflags},

    'LD'                => `mecab-config --cxx`,
    'INC'               => `mecab-config --cflags`,

    'clean'        => { FILES => 'MeCab.xs' }
);

これで無事に make test もとおります。

make test
PERL_DL_NONLAZY=1 /usr/local/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/01-sanity..................ok
t/02-basic...................ok
t/03-free....................ok
t/04-dclone..................ok
t/05-format..................ok
t/90-regression_tomi_args....skipped
all skipped: TODO
t/99-pod-coverage............ok
t/99-pod.....................ok
All tests successful, 1 test skipped.
Files=8, Tests=492, 1 wallclock secs ( 0.41 cusr + 0.10 csys = 0.51 CPU)

tools/benchmark.pl で簡単なベンチマークが計測できるのでやってみる。

perl benchmark.pl
             Rate      mecab text_mecab
mecab      27.7/s         --       -71%
text_mecab 97.1/s       250%         --

と言うことで、約 2.5 倍ほど高速になるみたいです。日本語処理を伴うサービスの場合、mecab-perl を Text::MeCab に置き換えるだけでそれなりの負荷低減が見込めそうです。Amazon Search とかも久々に手を入れるとするかなぁ・・・。

文章が大きくなると Text::MeCab は遅くなる場合もあるようです。(あったようです?)

一応自分でも計測してみました。ベンチの話は環境依存が多分にあるので皆様も是非鵜呑みにせず自分の環境でベンチ下さい。ウチの環境ではこんな感じ。

wget http://www.aozora.gr.jp/cards/000125/files/1317_23268.html

time mecab -Owakati < 1317_23268.html > /dev/null
real    0m0.317s
user    0m0.236s
sys     0m0.004s

time perl wakati-mecab.pl < 1317_23268.html > /dev/null
real    0m0.252s
user    0m0.145s
sys     0m0.086s

time perl wakati-text-mecab.pl < 1317_23268.html > /dev/null
real    0m0.228s
user    0m0.133s
sys     0m0.094s

wget http://www.aozora.gr.jp/cards/000096/files/2381_13352.html

time mecab -Owakati < 2381_13352.html > /dev/null
real    0m0.012s
user    0m0.008s
sys     0m0.003s

time perl wakati-mecab.pl < 2381_13352.html > /dev/null
real    0m0.035s
user    0m0.024s
sys     0m0.011s

time perl wakati-text-mecab.pl < 2381_13352.html > /dev/null
real    0m0.061s
user    0m0.051s
sys     0m0.010s

となって大きな文章でも問題なく?ってか mecab-perl も Text::MeCab も同じ速度でした。小さな文章はやっぱり高速みたい?と思ったら逆だった。mecab-perl の方が速いじゃん!!

あれー??ってかよくベンチスクリプト見たら、Text::MeCab の方、perl の push やら join で処理時間くってないかい?ってことで、今日はここまで。

- スポンサーリンク -