Answer exact-term description lookups from a map instead of a Lucene index - #5
Open
dionmcm wants to merge 1 commit into
Open
Answer exact-term description lookups from a map instead of a Lucene index#5dionmcm wants to merge 1 commit into
dionmcm wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Branch:
perf/exact-term-lookup-without-lucene· Module:snomed-drools-rf2-validatorProblem
DroolsDescriptionIndexhas an in-memory Lucene index, but nothing about the question it answers needs a search engine:StringField— a single token, never analysed,TermQuery— exact,Occur.FILTER— nothing scored,This is effectively exact-match implemented with an inverted index, and reading the stored id forces LZ4 decompression of a stored-fields block on every call.
Evidence
1,960 worker-thread samples from a full-Snapshot run, attributing each sample to its first frame in library code:
The leaf frames under it are entirely Lucene mechanics, none of which contribute to the answer:
Change
Two
HashMaps — active and inactive — from term to description ids. Same public method, same semantics, immutable result set.Values are
String[]rather thanSet<String>deliberately. There is roughly one distinct term per description (2.26M on this edition) and a single-elementHashSetcosts ~150 bytes of overhead against ~24 for a single-element array;using sets would have made this structure larger than the Lucene index it replaces, so this keeps heap pressure down. Terms shared by several descriptions are rare, so growing by one on collision is cheaper than carrying a
set everywhere.
Description ids are unique keys of
descriptionMap, so the ids held against one term cannot repeat andSet.ofis safe.This was the only Lucene user in the module, so the four now-unused
org.apache.lucenedependencies are removed. Removing them also drops theJava 23 or later ... please update Apache Lucenewarning from every run.Tests
DroolsDescriptionIndexTestcovers exact match, active/inactive separation of a shared term, several descriptions sharing a term, and — importantly — that lookups stay exact:"Heart","heart structure"and"Heart structures"must all miss"Heart structure". A tokenising or case-folding replacement would pass the happy path and fail these.Measurement
Rule execution 208s -> 54s (3.9x).
Total 307s -> 165s. Process CPU 1,832s -> 735s, so this is less work done, not better parallelism.
Building the structure also dropped the gap between
Components loadedandRunning testsfrom ~15s to ~4s.About this series
One of five independent performance changes to the Drools validation path, measured against a real 722,404-concept AU edition Snapshot. Each is a single commit on
master, builds and passes the full suite alone, and leaves the findings byte-identical: 10,949 before and after, with matching report TSVs.Together they take a full-Snapshot validation from 636s to 118s.