Lucene 2.4とLucene 2.0の検索速度比較
前回、Lucene 2.4と2.0でインデックス構築速度の比較をしたので、ついでに検索速度の比較もしてみました。
前回のエントリーでは、以下のようにインデックスを作成しました。
- データ: 日本語版Wikipediaのダンプから先頭20万記事
- インデックス形式:
- 記事タイトル: Store.YES, Index.ANALYZED(元文字列+インデックス)
- 記事本文: Store.COMPRESS, Index.ANALYZED(圧縮元文章+インデックス)
- アナライザ: CJKAnalyzer(bi-gram)
このインデックスに対し、ランダムに選ばれた1000件の記事タイトルをクエリとして検索を行い、所要時間を計測しました(5回測定して中央値を採用)。ちなみに、初回の検索はsearcherがウォームアップされていないので、2回目以降に比べて非常に遅いです。
結果は次のようになりました。
バージョン | Lucene 2.4.1 | Lucene 2.0.0 |
---|---|---|
検索時間 | 4173 ms | 8793 ms |
検索速度でも、Lucene 2.4がLucene 2.0を大幅に上回る結果になりました。
Lucene 2.4で使った検証用コードは以下です(2.0でも同等のコードを使用)。
public class LuceneSearchBenchmark { public static void main(String[] args) throws Exception { File dataFile = new File("C:/data/jawiki-20090124-pages-articles.xml"); File indexDir = new File("C:/data/index-2.4"); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader xmlReader = factory .createXMLStreamReader(new FileInputStream(dataFile)); List<String> keywords = new ArrayList<String>(200000); int count = 0; for (; xmlReader.hasNext(); xmlReader.next()) { if (!xmlReader.isStartElement()) { continue; } String elemName = xmlReader.getName().getLocalPart(); if (elemName.equals("title")) { keywords.add(xmlReader.getElementText()); if (++count >= 200000) { break; } } } Collections.shuffle(keywords); xmlReader.close(); IndexSearcher searcher = new IndexSearcher(indexDir.getPath()); Analyzer analyzer = new CJKAnalyzer(); List<Integer> result = new ArrayList<Integer>(); int trialCount = 5; for (int n = 1; n <= trialCount; n++) { long start = System.currentTimeMillis(); for (int i = 0; i < 1000; i++) { PhraseQuery phrase = new PhraseQuery(); TokenStream stream = analyzer.reusableTokenStream("body", new StringReader(keywords.get(i))); Token token = new Token(); while ((token = stream.next(token)) != null) { phrase.add(new Term("body", token.term())); } searcher.search(phrase, 100); if (i % 100 == 0) { System.out.println(i); } } long elapsed = System.currentTimeMillis() - start; result.add((int) elapsed); System.out.println(n + ": " + elapsed + " ms."); } Collections.sort(result); int finalResult = result.get(trialCount / 2); System.out.println("final result: " + finalResult + " ms."); } }