通过JNI使用C ++尖叫快速进行Lucene搜索
一天結束時,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 ,并且OS將破壞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
總結
以上是生活随笔為你收集整理的通过JNI使用C ++尖叫快速进行Lucene搜索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 360全景记录仪的十大排名(汽车360全
- 下一篇: 构建器模式:适用于代码,适用于测试