(转)HubbleDotNet 和 Lucene.net 性能对比测试
HubbleDotNet 从 2009 年11月份发布第一个版本以来, 只对 0.7 版本做过一次性能对比测试,原因是近一年来,HubbleDotNet一直在做性能优化,截至2010年9月,性能已经优化的差不多了,索引和查询的性能比 0.7 版本时提高了很多倍。这两天重新对HubbleDotNet 与 Lucene.Net 做了性能对比测试。下面就公布一下我的测试数据。
测试版本
HubbleDotNet 0.9.7.0
Lucene.Net 2.9.2.1
盘古分词 2.3.1.0
测试环境
Intel 双核 1.80 GHz, 2G Ram 笔记本电脑,硬盘转速 5400 转
Windows XP
测试数据
测试数据为430万行中文论文数据,索引论文标题和摘要,原始数据大小为 2G。
测试方法
索引
HubbleDotNet 采用被动方式 Append Only 模式对论文数据库现有表进行索引。索引后优化。
Lucene.Net 则是从数据库读取记录进行索引,数据存储在Lucene.Net 索引中。索引后优化。
搜索
搜索测试分三个测试用例
1. 测试单个词搜索,不同返回结果集大小时的单次搜索时间
2. 测试多个词同时搜索,不同返回结果集大小时的单次搜索时间
3. 测试相近结果集大小下,不同单词数量的单次搜索时间
测试方法为
HubbleDotNet 取消所有缓存设置,循环执行查询语句10次,计算平均值。重复这个过程3次,取最小的时间
Lucene.net 没有设置缓存的地方,所以就直接循环查询 10次,计算平均值。重复这个过程3次,取最小的时间
两者都是返回前25 条记录的 摘要数据,并按得分从大到小排序。
测试结果
索引
HubbleDotNet 索引(包括优化) 用时 5200 秒 (0.9 版本)
HubbleDotNet 1.0.1.0 版本索引部分算法又进行了优化,索引(包括优化) 用时 4611 秒
Lucene.net 索引(包括优化) 用时 8700 秒
HubbleDotNet 索引文件大小总和为 1.30 GB
Lucene.net 索引文件大小总和为 3.48GB
搜索
用例1
测试搜索单个单词,结果集大小分别在 10万,20万,50万,100万,200万,400万 级别两者的性能对比。
其中
HubbleDotNet (Match) 指采用Match 方法进行搜索,就是各个单词分量以或的方式匹配。
HubbleDotNet (Cache) 指采用Match 方法进行搜索,并打开数据缓存后的结果。
测试语句示例:
select top 25 docid, abstract from AllIndex where abstract match ‘基于‘ order by score desc
原始数据如下:
Word | Result | Lucene.net | HubbleDotNet Match |
HubbleDotNet Cache |
基于 | 97539 | 77.8 | 40.84 | 2.38 |
实验 | 171383 | 74.8 | 57.29 | 1.57 |
发展 | 501510 | 523 | 104.59 | 3.86 |
个 | 918853 | 114.8 | 126.95 | 4.07 |
. | 1956000 | 191.8 | 237.99 | 2.33 |
的 | 3991397 | 303 | 380.06 | 3.72 |
结论:
Lucene.net 在某些词上,不知道为什么会出现毛刺,比如 发展这个词,我重复测了多次,都是 500多毫秒,不知道为什么,可能和其索引的结构有关。
对于结果集大小在50万以内的情况,HubbleDotNet 要比Lucene.net 快不少。
而对于较大结果集,两者差别不大,不过 HubbleDotNet 的搜索算法不会对某些关键词出现毛刺,基本上是一个缓慢递增的过程。
用例2
测试搜索7个单词,多关键字查询,结果集大小分别在 15万,40万,80万,150万,300万,400万 级别两者的性能对比。
通常情况下,搜索都是多关键字的,所以这个测试可能更接近实际情况。
其中
HubbleDotNet (Match) 指采用Match 方法进行搜索,就是各个单词分量以或的方式匹配。
HubbleDotNet (Contains) 指采用Contains 方法进行搜索,就是各个单词分量以与的方式匹配。这个测试为和Match 相同关键字情况下的搜索耗时,但由于是与方式,结果集大小会比Match 要小很多。
HubbleDotNet (Cache) 指采用Match 方法进行搜索,并打开数据缓存后的结果。
测试语句示例:
select top 25 docid, abstract from AllIndex
where abstract match ‘塑料 构建 数学 群体 毅力 所有‘ order by score desc
select top 25 docid, abstract from AllIndex
where abstract contains ‘塑料 构建 数学 群体 毅力 所有‘ order by score desc
测试原始数据:
Word | Result | Lucene.net | HubbleDotNet Match |
HubbleDotNet Contains |
HubbleDotNet Cache |
塑料 构建 数学 群体 毅力 所有 | 153035 | 361.8 | 31.47 | 8.84 | 2.02 |
获得 教育 数学 群体 毅力 所有 | 408175 | 419.4 | 46.37 | 9.69 | 2.42 |
获得 教育 数学 群体 毅力 发展 | 788078 | 723.4 | 81.5 | 9.09 | 2.43 |
获得 教育 数学 个 毅力 发展 | 1485791 | 886.4 | 129.33 | 15.93 | 2.45 |
. 教育 数学 个 毅力 发展 | 2770563 | 1211.8 | 208.56 | 13.15 | 2.31 |
数学 的 教育 个 毅力 发展 | 4034774 | 1491.2 | 285.83 | 13.39 | 1.2 |
结论:
多关键字情况下 HubbleDotNet 比 Lucene.Net 具有明显的优势,Match 方法大概比Lucene.net 快5-10倍,而Contains 方法则比Lucene.net 快上百倍。
用例3
测试搜索1个单词到7个单词,结果集大小分别在100万级别时两者的性能对比。
这个测试主要是想看看搜索关键字的数量对搜索效率的影响。
其中
HubbleDotNet (Match) 指采用Match 方法进行搜索,就是各个单词分量以或的方式匹配。
HubbleDotNet (Contains) 指采用Contains 方法进行搜索,就是各个单词分量以与的方式匹配。这个测试为和Match 相同关键字情况下的搜索耗时,但由于是与方式,结果集大小会比Match 要小很多。
HubbleDotNet (Cache) 指采用Match 方法进行搜索,并打开数据缓存后的结果。
测试原始数据:
Word | Result | Lucene.net | HubbleDotNet Match |
HubbleDotNet Contains |
HubbleDotNet Cache |
Number |
个 | 918853 | 114.8 | 126.95 | 109.74 | 2.33 | 1 |
个 毅力 | 919277 | 193.4 | 57.88 | 57.52 | 2.41 | 2 |
毅力 个 配方 | 929364 | 202.6 | 63.38 | 3.86 | 1.11 | 3 |
毅力 个 数学 配方 | 948084 | 300.9 | 59.08 | 5.31 | 2.32 | 4 |
毅力 个 数学 配方 群体 | 958049 | 291.6 | 64.07 | 5.54 | 2.05 | 5 |
毅力 个 数学 获得 配方 群体 | 1032700 | 330.1 | 80.59 | 5.5 | 1.09 | 6 |
毅力 个 数学 获得 配方 群体 密切 | 1066529 | 334.6 | 85.84 | 5.78 | 2.35 | 7 |
结论:
在单个关键字时,Lucene.net 和 HubbleDotNet 的搜索速度是接近的,但随着关键字的增多,两者的差距就明显增大了,HubbleDotNet 具有明显的优势。
附录
Lucene.Net 测试的部分代码
string keywords = q;
IndexSearcher search = new IndexSearcher(indexDir);
QueryParser queryParser = new QueryParser("abstract", new PanGuAnalyzer());
Query query = queryParser.Parse(q);
Hits hits = search.Search(query);
List<News.TNews> result = new List<News.TNews>();
recCount = hits.Length();
int i = (pageNo - 1) * pageLen;
while (i < recCount && result.Count < pageLen)
{
News.TNews news = new TNews();
news.Content = hits.Doc(i).Get("abstract");
result.Add(news);
i++;
}
search.Close();
return result;
这是搜索部分的代码,pageLen = 25
转载自:http://www.cnblogs.com/eaglet/archive/2010/09/03/1816856.html