読者です 読者をやめる 読者になる 読者になる

唯物是真 @Scaled_Wurm

プログラミング(主にPython2.7)とか機械学習とか

xargsを使った並列化を試したメモ

自然言語処理

↑の辺りの記事を読んでxargsによる並列化を試してみたメモ。
結果を先に書いておくと、残念ながら並列化してもあまり速くならなかった。

もしかしたらコマンドの使い方が怪しいかも……?

とりあえず目的はMeCabを並列に実行すること。

300弱のファイルで試した。
並列数Pと渡す引数の数nは適当に決めた。

1.ファイルごとに並列

カレントディレクトリ以下の.txtファイル名を全部取ってきて10並列でMeCabに投げて出力をtxtファイル名+.mecabファイルにリダイレクトする。

わざわざシェル(sh)経由でMeCabを起動しているのは、.mecabファイルに標準出力をリダイレクトさせるようにするため。

find . -name '*.txt' -print0 | xargs -0 -I{} -P10 -n1 sh -c 'mecab "{}" > "{}.mecab"'

2.シェルの起動回数を減らす

遅い原因がテキストファイルごとにshを起動しているせいかと思ったので、ファイル名をまとめて渡してシェル内でforループで回すようにした。

find . -name '*.txt' -print0 | xargs -0 -P10 -n20 sh -c 'for arg in "$0" "$@"; do mecab "${arg}" > "${arg}.mecab"; done'

3.分割した後にforループを使わずcatでまとめてからMeCabにかけて、MeCabを呼ぶ回数を減らす。

更にMeCabを呼ぶ回数も減らしてみた。

find . -name '*.txt' -print0 | xargs -0 -P10 -n20 sh -c 'cat "$0" "$@" | mecab > "$0.mecab"'

結果

10並列で動かしていたが、2から4倍程度の処理速度だった。
しかもサーバー側の問題なのか、実行するたびに処理時間にかなりばらつきがあった。

上に書いた3種類のやり方で試してみたが、残念ながらあまりどれが速いかというのは明らかではなかった。

蛇足

以下のようにMeCabを実行したら結果が一瞬で返ってきて?となったのですが、MeCabって引数の最初のファイル1つだけしか処理しないんですね……。

mecab *.txt
-->