You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2023/08/03 05:17:58 UTC

[lucene] branch main updated: Reduce overhead of disabling scoring on `BooleanScorer`. (#12475)

This is an automated email from the ASF dual-hosted git repository.

jpountz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/main by this push:
     new acffcfaaf0d Reduce overhead of disabling scoring on `BooleanScorer`. (#12475)
acffcfaaf0d is described below

commit acffcfaaf0d7ef4650fe542cb3f11a6cc31ac7b9
Author: Adrien Grand <jp...@gmail.com>
AuthorDate: Thu Aug 3 07:17:52 2023 +0200

    Reduce overhead of disabling scoring on `BooleanScorer`. (#12475)
    
    This is a subset of #12415, which I'm extracting to its own pull request in
    order to have separate data points in nightly benchmarks.
    
    Results on `wikimedium10m` and `wikinightly` counting tasks:
    
    ```
                           CountTerm     4624.91      (6.4%)     4581.34      (6.4%)   -0.9% ( -12% -   12%) 0.640
                     CountAndHighMed      280.03      (4.5%)      280.15      (4.4%)    0.0% (  -8% -    9%) 0.974
                         CountPhrase        7.22      (3.0%)        7.24      (1.8%)    0.3% (  -4% -    5%) 0.728
                    CountAndHighHigh       52.84      (4.9%)       53.12      (5.6%)    0.5% (  -9% -   11%) 0.755
                            PKLookup      232.01      (3.6%)      235.45      (2.8%)    1.5% (  -4% -    8%) 0.144
                     CountOrHighHigh       42.37      (6.1%)       56.04      (9.1%)   32.3% (  16% -   50%) 0.000
                      CountOrHighMed       30.56      (6.5%)       40.46      (9.8%)   32.4% (  15% -   52%) 0.000
    ```
---
 .../org/apache/lucene/search/BooleanScorer.java    | 48 +++++++++++++---------
 1 file changed, 29 insertions(+), 19 deletions(-)

diff --git a/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java b/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
index 5bc9c979375..1648ecc5f8a 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
@@ -109,7 +109,7 @@ final class BooleanScorer extends BulkScorer {
     }
   }
 
-  final Bucket[] buckets = new Bucket[SIZE];
+  final Bucket[] buckets;
   // This is basically an inlined FixedBitSet... seems to help with bound checks
   final long[] matching = new long[SET_SIZE];
 
@@ -119,6 +119,7 @@ final class BooleanScorer extends BulkScorer {
   final Score score = new Score();
   final int minShouldMatch;
   final long cost;
+  final boolean needsScores;
 
   final class OrCollector implements LeafCollector {
     Scorable scorer;
@@ -133,9 +134,13 @@ final class BooleanScorer extends BulkScorer {
       final int i = doc & MASK;
       final int idx = i >>> 6;
       matching[idx] |= 1L << i;
-      final Bucket bucket = buckets[i];
-      bucket.freq++;
-      bucket.score += scorer.score();
+      if (buckets != null) {
+        final Bucket bucket = buckets[i];
+        bucket.freq++;
+        if (needsScores) {
+          bucket.score += scorer.score();
+        }
+      }
     }
   }
 
@@ -154,19 +159,20 @@ final class BooleanScorer extends BulkScorer {
       throw new IllegalArgumentException(
           "This scorer can only be used with two scorers or more, got " + scorers.size());
     }
-    for (int i = 0; i < buckets.length; i++) {
-      buckets[i] = new Bucket();
+    if (needsScores || minShouldMatch > 1) {
+      buckets = new Bucket[SIZE];
+      for (int i = 0; i < buckets.length; i++) {
+        buckets[i] = new Bucket();
+      }
+    } else {
+      buckets = null;
     }
     this.leads = new BulkScorerAndDoc[scorers.size()];
     this.head = new HeadPriorityQueue(scorers.size() - minShouldMatch + 1);
     this.tail = new TailPriorityQueue(minShouldMatch - 1);
     this.minShouldMatch = minShouldMatch;
+    this.needsScores = needsScores;
     for (BulkScorer scorer : scorers) {
-      if (needsScores == false) {
-        // OrCollector calls score() all the time so we have to explicitly
-        // disable scoring in order to avoid decoding useless norms
-        scorer = BooleanWeight.disableScoring(scorer);
-      }
       final BulkScorerAndDoc evicted = tail.insertWithOverflow(new BulkScorerAndDoc(scorer));
       if (evicted != null) {
         head.add(evicted);
@@ -181,15 +187,19 @@ final class BooleanScorer extends BulkScorer {
   }
 
   private void scoreDocument(LeafCollector collector, int base, int i) throws IOException {
-    final Score score = this.score;
-    final Bucket bucket = buckets[i];
-    if (bucket.freq >= minShouldMatch) {
-      score.score = (float) bucket.score;
-      final int doc = base | i;
-      collector.collect(doc);
+    if (buckets != null) {
+      final Score score = this.score;
+      final Bucket bucket = buckets[i];
+      if (bucket.freq >= minShouldMatch) {
+        score.score = (float) bucket.score;
+        final int doc = base | i;
+        collector.collect(doc);
+      }
+      bucket.freq = 0;
+      bucket.score = 0;
+    } else {
+      collector.collect(base | i);
     }
-    bucket.freq = 0;
-    bucket.score = 0;
   }
 
   private void scoreMatches(LeafCollector collector, int base) throws IOException {