Hatena::ブログ(Diary)

駄文生産所 このページをアンテナに追加 RSSフィード

2011-05-29

Goist速度計測

形態素解析エンジンGoistの速度を計測した。

以前行ったIgoの結果を含めて簡単に比較する。


環境



測定内容


結果

実行時間
Java(Igo)VW(Igo)VW(Goist)CogVM(Goist)SqueakVM(Goist)
834222926393582 (2回目)
4272 (初回)
27362

単位ミリ


実行時間
Java(Igo)VW(Igo)VW(Goist)CogVM(Goist)SqueakVM(Goist)
12.673.164.29 (2回目)
5.12 (初回)
32.8
0.320.8411.36 (2回目)
1.62 (初回)
10.37
0.230.620.741 (2回目)
1.19 (初回)
7.64

同じロジックで解を出しているのだが、VW(Igo)に比べてVW(Goist)は少々遅い。これは、わかりやすさ優先で冗長に書いた分、辞書構造が変わっていたり、メソッド呼び出しが増えるなどしているので想定通り。まずまず。

CogVMの性能がVisualWorksVMの性能に迫っていて驚かされた。まぁ同じ人が作っているわけだが。SqueakUIフレームワークであるMorphicが絡むと、そこにCPUパワーが取られてしまいがちだが、Webアプリプラットフォームとしてなら、かなりやれそう。ただ、IO周りが遅いので、そちらに引っ張られるかもしれない。

素のSqueakVMにはそろそろ引退かな。

辞書の読み込み時間については、最初に一度読み込んだ後はそれを使いまわすことを想定しているため、重視していない。概ね、Java(Igo)は一瞬、VW(Igo)は7秒、VW(Goist)は15秒、CogVM(Goist)は30秒、SqueakVM(Goist)は75秒程度で、Javaの速さが際立つ。というよりはSmalltalk陣営が遅い。Ruby(Igo)も3秒程度であった。

(追記)

実装が悪かった。VW(Goist)は4秒、CogVM(Goist)は10秒程度まで縮められた。それでもまだJavaRubyが速いが、際立って遅いというわけではないと思われる。


おまけ

CogVMの場合の、各回の結果を載せる。

JITが効いている様子が窺える。

"Squeak-CogVM(Goist) 初回"
6422 milliseconds
4355 milliseconds
4094 milliseconds
3947 milliseconds
4045 milliseconds
4114 milliseconds
4176 milliseconds
4226 milliseconds
3459 milliseconds
3883 milliseconds
Average: 4272 milliseconds
"Squeak-CogVM(Goist) 2回目"
3358 milliseconds
3391 milliseconds
3931 milliseconds
3395 milliseconds
3832 milliseconds
3373 milliseconds
3869 milliseconds
3381 milliseconds
3916 milliseconds
3375 milliseconds
Average: 3582 milliseconds

使用コード

VisualWorks Smalltalk
dictionaryDirectoryPath := 'C:\ipadic-test'.
dictionary := GDictionary from: dictionaryDirectoryPath.
tagger := dictionary newTagger.
contents := ('c:\temp\igo\kokoro.txt' asFilename withEncoding: #'utf-8') readStream contents.
sum := 0.
10 timesRepeat: [
    | timeToRun |
    timeToRun := Time millisecondsToRun: [tagger parse: contents].
    
    sum := sum + timeToRun.
    Transcript cr; show: timeToRun printString , ' milliseconds'.
].
Transcript cr; show: 'Average: ' , (sum // 10) printString , ' milliseconds'. 
Squeak Smalltalk
dictionaryDirectoryPath := 'C:\ipadic-squeak-test'.
dictionary := GDictionary from: dictionaryDirectoryPath.
tagger := dictionary newTagger.
fs := FileStream readOnlyFileNamed: 'c:\temp\igo\kokoro.txt'.
contents := fs contents.
fs close.
sum := 0.
10 timesRepeat: [
    | timeToRun |
    timeToRun := Time millisecondsToRun: [tagger parse: contents].
    
    sum := sum + timeToRun.
    Transcript cr; show: timeToRun printString , ' milliseconds'.
].
Transcript cr; show: 'Average: ' , (sum // 10) printString , ' milliseconds'. 

2011-05-09

形態素解析で速度比較

IgoのVisualWorks版がどの程度やれるのか、興味があったので測ってみた。

JavaRubyVisualWorks比較VisualWorksはIgoとDLL/CCを使用したMeCabバインディング


環境


測定内容


結果

 JavaVW(Igo)VW(MeCab)Ruby
100行410292970
300行14356819442
1000行53170254251818
全て(10731行)83422292991待てません

単位ミリ


結果としては、Java > VisualWorks(Igo) > VisualWorks(MeCab) >>> RubyJava : VisualWorks : Ruby = 1 : 3 : 1000 程度。ちょっと異常な感。

基本的には同じロジックを使用しているはずなので、Rubyの使い方を間違えたのかと思う程に遅い。100行〜1000行の間で処理時間が約100倍になっているので、テキストをすべてパースし終えるには、、、最小で見積もっても7時間はかかる。

JavaVisualWorksが共に内部では文字を2バイト固定で保持しているのに対して、RubyUTF-8なのが問題なのだと推測する。UTF-16やUTF-32、UCS-2を指定すれば劇的に改善するかもしれない。

VisualWorksMeCabバインディングの方が遅かった。Java版のIgoとMeCabの速度はそう変わらないそうなので、DLL/CCオーバーヘッドがバカにならないようだ。

IgoのVisualWorks版は、2000文字で10ミリ秒、20000文字で200ミリ秒と考えると、大抵の場面で使用に耐えるレベルだと思う。


使用コード

Java
package net.reduls.igo;

import java.io.FileReader;

public class Main {
    public static void main(String[] args) {
        try {
            Tagger tagger = new Tagger( "C:\\temp\\igo\\ipadic" );

            FileReader in = new FileReader("C:\\temp\\igo\\kokoro.txt");
            StringBuilder sb = new StringBuilder();
            int c;
            while ((c = in.read()) != -1) {
                sb.append((char)c);
            }
            in.close();
            String contents = sb.toString();
            
            long sum = 0;
            for(int i = 0; i < 10; i++) {
                long start = System.currentTimeMillis();
                tagger.parse(contents);
                long timeToRun = System.currentTimeMillis() - start;
            
                sum = sum + timeToRun;
                System.out.println(timeToRun + " milliseconds");
            }
            System.out.println("Average: " + (sum / 10) + " milliseconds");
            
        } catch (Exception e) {
            // noop
        } 
    }
}
VisualWorks Smalltalk
"Igo"
| dicDirPath tagger contents sum |
dicDirPath := 'C:\temp\igo\ipadic'.
tagger := IgoTagger dicDir: dicDirPath.
contents := ('c:\temp\igo\kokoro.txt' asFilename withEncoding: #'utf-8') readStream contents.
sum := 0.
10 timesRepeat: [
    | timeToRun |
    timeToRun := Time millisecondsToRun: [tagger parse: contents].
    
    sum := sum + timeToRun.
    Transcript cr; show: timeToRun printString , ' milliseconds'.
].
Transcript cr; show: 'Average: ' , (sum // 10) printString , ' milliseconds'.
"MeCab"
| tagger contents sum |
tagger := MeCabTagger new.
contents := ('c:\temp\igo\kokoro.txt' asFilename withEncoding: #'utf-8') readStream contents.
sum := 0.
10 timesRepeat: [
    | timeToRun |
    timeToRun := Time millisecondsToRun: [tagger parse: contents].
    
    sum := sum + timeToRun.
    Transcript cr; show: timeToRun printString , ' milliseconds'.
].
Transcript cr; show: 'Average: ' , (sum // 10) printString , ' milliseconds'.

Ruby
require 'rubygems'
require 'igo-ruby'

tagger = Igo::Tagger.new("c:/temp/igo/ipadic")

f = open("c:/temp/igo/kokoro.txt")
contents = f.read
f.close

sum = 0
10.times{
    start = Time.now
    tagger.parse(contents)
    timeToRun = (Time.now - start) * 1000
    
    sum = sum + timeToRun
    puts("#{timeToRun} milliseconds")
}
puts("Average: #{sum / 10} milliseconds")

2011-05-08

形態素解析エンジン Igo for VisualWorks

形態素解析エンジンIgo(http://igo.sourceforge.jp/)をCincom Smalltalk VisualWorks移植したもの。

概ねMeCab互換日本語形態素解析Smalltalkネイティブ環境で行える。

辞書の構築に必要な部分は未実装なので、本家Igoを使用する必要がある。

実装については、主にIgo-ruby(https://github.com/kyow/igo-ruby)を参考にさせていただいた。

辞書の構築には本家IgoのBuildDicコマンドを使用する必要がある。手順に関しては以下が詳しい。

Java形態素解析エンジン「Igo」を試してみる

http://www.mwsoft.jp/programming/munou/igo_install.html

また、「java.lang.OutOfMemoryError: Java heap space」などと文句を言われた場合は、

java -Xmx1024m -cp igo-0.4.2.jar net.reduls.igo.bin.BuildDic ipadic mecab-ipadic-2.7.0-20070801 EUC-JP

のように、メモリを多めにJVMに食べさせる。


"形態素解析"
"出力は次の順:表層形, 品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音"

| dicDirPath tagger |
dicDirPath:= 'C:\igo\ipadic'.
tagger := IgoTagger dicDir: dicDirPath.
(tagger parse: '吾輩は猫である。名前はまだ無い。') 
    do: [:each | Transcript cr; show: each printString].

"
吾輩, 名詞,代名詞,一般,*,*,*,吾輩,ワガハイ,ワガハイ
は, 助詞,係助詞,*,*,*,*,は,ハ,ワ
猫, 名詞,一般,*,*,*,*,猫,ネコ,ネコ
で, 助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ
ある, 助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル
。, 記号,句点,*,*,*,*,。,。,。
名前, 名詞,一般,*,*,*,*,名前,ナマエ,ナマエ
は, 助詞,係助詞,*,*,*,*,は,ハ,ワ
まだ, 副詞,助詞類接続,*,*,*,*,まだ,マダ,マダ
無い, 形容詞,自立,*,*,形容詞・アウオ段,基本形,無い,ナイ,ナイ
。, 記号,句点,*,*,*,*,。,。,。。"

"※Ver1.0のコスト計算に誤りがあったためVer1.1で修正。上記出力例は修正後のもの"
"分かち書き"
| dicDirPath tagger |
dicDirPath := 'C:\igo\ipadic'.
tagger := IgoTagger dicDir: dicDirPath.
(tagger wakati: '吾輩は猫である。名前はまだ無い。') 
    do: [:each | Transcript show: each]
    separatedBy: [Transcript show: '|'].

"吾輩|は|猫|で|ある|。|名前|は|まだ|無い|。"