vc++调用jni
最终,当Lucene执行查询时,在初始设置后,真正的热点通常是相当基本的代码,该代码对整数docID,术语频率和位置的顺序块进行解码,并将它们匹配(例如,对BooleanQuery
并集或交集) ),则为每个匹配项计算得分,并在收集过程中保存具有竞争力的匹配项。 甚至显然复杂的查询(如FuzzyQuery
或WildcardQuery
FuzzyQuery
经过重写过程,从而将其简化为更简单的形式(如BooleanQuery
。 Lucene的热点非常简单,以至于无法通过将它们移植到本地C ++(通过JNI)来对其进行优化!
因此,我这样做了,创建了lucene-c-boost github项目,其结果是令人兴奋的:
|
这些结果显示在完整的,多领域的Wikipedia英语索引中,包含33.3 M个文档。 除了令人惊讶的加速性能外,还很高兴看到优化的C ++版本的差异(StdDev列)通常较低,因为(大部分)热点已被排除在等式之外。
该API易于使用,并且可与默认编解码器一起使用,因此您无需尝试重新编制索引即可:代替IndexSearcher.search
,请调用NativeSearch.search
。 如果查询可以优化,它将被优化; 否则,它将无缝地回IndexSearcher.search
。 它与Lucene完全分离,并与现有的Lucene 4.3.0 JAR一起使用,使用Java的反射API来获取必要的位。
这都是非常新的代码,我敢肯定有很多令人兴奋的错误,但是(在经过一些有趣的调试之后!)使用NativeSearch.search
时,所有Lucene核心测试现在都可以通过。
这不是Lucene的C ++端口
此代码绝对不是Lucene的常规C ++端口。 相反,它实现了一组非常狭窄的类,特别是常见的查询类型。 这些实现不是通用的:它们硬编码(专门化)特定代码,删除所有类似Scorer
, DocsEnum
, Collector
, DocValuesProducer
等的抽象。
在何时应用优化存在一些主要限制:
- 到目前为止仅在Linux和Intel CPU上进行了测试
- 需要Lucene 4.3.x
- 必须将
NativeMMapDirectory
用作Directory
实现,该实现将整个文件映射到RAM(避免基于Java的MMapDirectory
必须执行的分块) - 必须使用默认编解码器
- 仅支持按分数排序
- 没有一个优化的实现使用
advance
:首先,此代码相当复杂,要移植到C ++会花费很多工作;其次,受益于先进的查询通常已经非常快了,因此我们不妨将它们留在Java中
BooleanQuery
已优化,但仅当所有子句都是针对同一字段的TermQuery
时才进行优化。
C ++不比Java快!
无论如何,不一定如此:在有人大声疾呼这些结果如何“证明” Java比C ++慢得多之前,请记住,这远非“纯粹的” C ++ vs Java测试。 至少有以下三个单独的更改混合在一起:
- 算法更改。 例如, lucene-c-boost有时使用
BooleanScorer
,其中Lucene使用BooleanScorer2
。 确实,我们需要修复Lucene来进行类似的算法更改(当它们更快时)。 特别是,在上述结果中包括Not
子句以及IntNRQ
所有OrXX
查询都将从算法更改中受益。 - 代码专业化: lucene-c-boost将搜索作为强大的可怕外观函数来实现,从而删除了所有不错的Lucene抽象。 尽管在Lucene中显然需要抽象,但是不幸的是,它们增加了运行时的开销,因此删除这些抽象会带来一些好处。
- C ++与Java
究竟是哪一部分收益多少尚不清楚。 实际上,我需要创建“匹配”的专用Java源代码来进行更纯粹的测试。
此代码很危险!
具体地说,每当将本地C ++代码嵌入Java时,Java开发人员都认为我们抛弃了C ++带来的所有这些有趣的问题,总是存在风险。 例如,如果存在错误(可能是!),或者甚至是应用程序滥用了无辜的API,例如在其他线程仍在使用IndexReader
时意外关闭了IndexReader
,则该过程将遇到Segmentation Fault ,并且操作系统将破坏JVM。 。 可能还有内存泄漏! 而且,是的,C ++源代码甚至使用goto语句 。
工作正在进行中…
这是一项正在进行的工作,仍然有许多想法需要探索。 例如,Lucene的4.3.x版的默认PostingsFormat
店大端多头,这意味着小端的Intel CPU必须做字节交换的每个帖子块进行解码时,这么一件事是尝试一个PostingsFormat
在搜索时CPU更好地优化。 位置查询,过滤器和嵌套BooleanQuery
以及某些配置(例如,省略规范的字段)尚未进行优化。 欢迎补丁!
尽管如此,初步的结果还是很有希望的,如果您愿意冒险冒险以换取大幅度的加速,请稍作调整并报告。
翻译自: https://www.javacodegeeks.com/2013/06/screaming-fast-lucene-searches-using-c-via-jni.html
vc++调用jni