Skip to content

Commit 14a85ce

Browse files
committed
Make calls to BM25Scorer#score inlinable.
I ran experiments locally that suggest that some of the performance decrease from type pollution (mikemccand/luceneutil#436) can be attributed to calls to `SimScorer#score` no longer being inlinable since they are polymorphic. This change helps `BM25Scorer` remain inlinable using similar tricks that we are applying for `Bits#get` and `ImpactsEnum#nextDoc`/`ImpactsEnum#advance`. Hopefully changes such as apache#15039 will help improve performance with other similarities as well in the future.
1 parent 90be960 commit 14a85ce

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

lucene/core/src/java/org/apache/lucene/search/ScorerUtil.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
import java.util.stream.StreamSupport;
2323
import org.apache.lucene.codecs.lucene103.Lucene103PostingsFormat;
2424
import org.apache.lucene.index.ImpactsEnum;
25+
import org.apache.lucene.search.similarities.BM25Similarity;
26+
import org.apache.lucene.search.similarities.Similarity;
27+
import org.apache.lucene.search.similarities.Similarity.SimScorer;
2528
import org.apache.lucene.util.Bits;
2629
import org.apache.lucene.util.FixedBitSet;
2730
import org.apache.lucene.util.MathUtil;
@@ -98,6 +101,19 @@ static Bits likelyLiveDocs(Bits acceptDocs) {
98101
}
99102
}
100103

104+
/**
105+
* Optimize the given {@link Similarity} for the case when it is a {@link BM25Similarity}. This
106+
* helps make calls to {@link SimScorer#score(float, long)} inlinable, which in-turn helps speed
107+
* up query evaluation.
108+
*/
109+
static Similarity likelyBM25Similarity(Similarity similarity) {
110+
if (similarity instanceof BM25Similarity) {
111+
return similarity;
112+
} else {
113+
return new FilterSimilarity(similarity);
114+
}
115+
}
116+
101117
private static class FilterBits implements Bits {
102118

103119
private final Bits in;
@@ -117,6 +133,43 @@ public int length() {
117133
}
118134
}
119135

136+
private static class FilterSimilarity extends Similarity {
137+
138+
private final Similarity similarity;
139+
140+
FilterSimilarity(Similarity similarity) {
141+
this.similarity = similarity;
142+
}
143+
144+
@Override
145+
public SimScorer scorer(
146+
float boost, CollectionStatistics collectionStats, TermStatistics... termStats) {
147+
return new FilterSimScorer(similarity.scorer(boost, collectionStats, termStats)) {
148+
@Override
149+
public Explanation explain(Explanation freq, long norm) {
150+
return in.explain(freq, norm);
151+
}
152+
};
153+
}
154+
}
155+
156+
private static class FilterSimScorer extends SimScorer {
157+
158+
protected final SimScorer in;
159+
160+
FilterSimScorer(SimScorer scorer) {
161+
this.in = scorer;
162+
}
163+
164+
@Override
165+
public float score(float freq, long norm) {
166+
return in.score(freq, norm);
167+
}
168+
169+
// Don't override explain() here since it has a default impl, for consistency with other Filter*
170+
// classes.
171+
}
172+
120173
/**
121174
* Compute a minimum required score, so that (float) MathUtil.sumUpperBound(minRequiredScore +
122175
* maxRemainingScore, numScorers) <= minCompetitiveScore. The computed value may not be the

lucene/core/src/java/org/apache/lucene/search/TermQuery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public TermWeight(
5656
}
5757
this.scoreMode = scoreMode;
5858
this.termStates = termStates;
59-
this.similarity = searcher.getSimilarity();
59+
this.similarity = ScorerUtil.likelyBM25Similarity(searcher.getSimilarity());
6060

6161
final CollectionStatistics collectionStats;
6262
final TermStatistics termStats;

0 commit comments

Comments
 (0)