JiroSearch の現在公開している版は、 index の生成を、最も基本的な方法、つまり、 単一のスレッドで indexWriter を順に呼ぶだけの処理を行っている。 おそらく、これは最も効率のよくない方法で、 大量のインデックスを作ると時間がかかりすぎるのではないか。
ということで、 マルチスレッドを使って org.apache.lucene.store.RAMDirectory を使って index を生成ながら、 最後に FSDirectory にマージする、 という方法がよく紹介されているようだ。 試しに、 インデックスの生成を RAMDirectory を使った処理にまず置き換えてみた。 すると、 当然だが大量のインデックスを作るときに、 うまくやらないと大量にメモリを使うことになる。
この時点でまだスレッドは単一である。 ターゲットになっているファイルは約60万あって、 これを約5万個に分けてインデックスを別々に作ってみると、 全て生成するのに、約 174分かかった。
この結果、15個の index に分かれた状態になっている。 Lucene は複数 index を同時検索することができるから、 このままでも使えるのだが、 試しに、1つの index にマージしてみた。 これには約 30 分かかった。 処理時間を見ていると、 最終結果になるインデックスに1つずつインデックスを追加していくため、 後になればなるほど時間がかかっている。
高速化する余力があるなら、 このあたり(60万ファイル / 200分) を一つの目安にすればいいと思う。 もちろん、状況によってこの時間は大きく変化すると思われる。 今回使ったマシンは Fedora 6 (linux)、 CPU が Pentium 4 2.8MHz、 メモリが 1GB、 という環境である。
index を生成するときに、 CJKAnalyzer を使ったが、 たまに MaxFieldLength をオーバーしているようだ。 この値はデフォルトで 10,000 なのだが、 10,000 だとちょっと少ないと思ったので 30,000 に増やしたのだが、 まだ足りなかった。
このメッセージを出すには、 IndexWriter の setInfoStream メソッドを使って、 例えば次のようにすればいい。 ただし、こうすると他の情報も大量に出てくる。
indexWriter.setInfoStream(System.out);