Skip to content

Commit b90b9de

Browse files
gaobinlongjavanna
authored andcommitted
Optimize TopGroups.merge() maxScore computation for relevance sorting (#15879)
When docSort is Sort.RELEVANCE, derive each group's maxScore directly from mergedTopDocs.scoreDocs[0] instead of accumulating across shards via nonNANmax. Also hoist docSort.equals(Sort.RELEVANCE) into a local boolean to avoid repeated equals() calls in the per-group and per-shard loops. Signed-off-by: Binlong Gao <gbinlong@amazon.com>
1 parent 6a0afa2 commit b90b9de

2 files changed

Lines changed: 13 additions & 4 deletions

File tree

lucene/CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ Optimizations
105105

106106
* GITHUB#15779: Improve BytesRefHash.add performance by optimize rehash operation (tyronecai)
107107

108+
* GITHUB#15879: Optimize TopGroups.merge() maxScore computation for relevance sorting (Binlong Gao)
109+
108110
* GITHUB#15896: Skip heavy TreeSet opts for the first group in SearchGroup#merge (Binlong Gao)
109111

110112
* GITHUB#15886: Cache frozen FieldType to skip redundant schema validation. (Tim Brooks)

lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroups.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ public static <T> TopGroups<T> merge(
153153
final GroupDocs<T>[] mergedGroupDocs = new GroupDocs[numGroups];
154154

155155
final TopDocs[] shardTopDocs;
156-
if (docSort.equals(Sort.RELEVANCE)) {
156+
final boolean sortByRelevance = docSort.equals(Sort.RELEVANCE);
157+
if (sortByRelevance) {
157158
shardTopDocs = new TopDocs[shardGroups.length];
158159
} else {
159160
shardTopDocs = new TopFieldDocs[shardGroups.length];
@@ -187,7 +188,7 @@ public static <T> TopGroups<T> merge(
187188
}
188189
*/
189190

190-
if (docSort.equals(Sort.RELEVANCE)) {
191+
if (sortByRelevance) {
191192
shardTopDocs[shardIDX] =
192193
new TopDocs(shardGroupDocs.totalHits(), shardGroupDocs.scoreDocs());
193194
} else {
@@ -200,15 +201,21 @@ public static <T> TopGroups<T> merge(
200201
shardTopDocs[shardIDX].scoreDocs[i].shardIndex = shardIDX;
201202
}
202203

203-
maxScore = nonNANmax(maxScore, shardGroupDocs.maxScore());
204+
if (!sortByRelevance) {
205+
maxScore = nonNANmax(maxScore, shardGroupDocs.maxScore());
206+
}
204207
assert shardGroupDocs.totalHits().relation() == Relation.EQUAL_TO;
205208
totalHits += shardGroupDocs.totalHits().value();
206209
scoreSum += shardGroupDocs.score();
207210
}
208211

209212
final TopDocs mergedTopDocs;
210-
if (docSort.equals(Sort.RELEVANCE)) {
213+
if (sortByRelevance) {
211214
mergedTopDocs = TopDocs.merge(docOffset + docTopN, shardTopDocs);
215+
// When sorting by relevance, the highest-scoring doc is first, so we can
216+
// derive maxScore directly instead of accumulating across shards.
217+
maxScore =
218+
mergedTopDocs.scoreDocs.length == 0 ? Float.NaN : mergedTopDocs.scoreDocs[0].score;
212219
} else {
213220
mergedTopDocs = TopDocs.merge(docSort, docOffset + docTopN, (TopFieldDocs[]) shardTopDocs);
214221
}

0 commit comments

Comments
 (0)