Lucene - Core
  1. Lucene - Core
  2. LUCENE-6850

BooleanWeight should not use BS1 when there is a single non-null clause

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 5.4, 6.0
    • Component/s: None
    • Labels:
      None
    • Lucene Fields:
      New

      Description

      When a disjunction has a single non-null scorer, we still use BS1 for bulk-scoring, which first collects matches into a bit set and then calls the collector. This is inefficient: we should just call the inner bulk scorer directly and wrap the scorer to apply the coord factor (like BooleanTopLevelScorers.BoostedScorer does).

      1. LUCENE-6850.patch
        14 kB
        Adrien Grand
      2. LUCENE-6850.patch
        7 kB
        Adrien Grand

        Activity

        Hide
        Adrien Grand added a comment -

        Here is a patch. BooleanWeight.bulkScorer now has the same optimization as BooleanWeight.scorer in the case that only one of the optional clauses creates a non-null scorer.

        Show
        Adrien Grand added a comment - Here is a patch. BooleanWeight.bulkScorer now has the same optimization as BooleanWeight.scorer in the case that only one of the optional clauses creates a non-null scorer.
        Hide
        Adrien Grand added a comment - - edited

        I iterated on the previous patch in order to also optimize the case when all clauses return a non-null BulkScorer, but some windows of 2048 documents only contain matches for one of the sub scorers: in that case we can call the collector directly instead of going through a bitset and replaying. luceneutil on wikimedium10m shows a nice speedup for OrHighLow:

                            TaskQPS baseline      StdDev   QPS patch      StdDev                Pct diff
                          Fuzzy2       54.93     (13.3%)       51.19     (16.9%)   -6.8% ( -32% -   26%)
                      OrHighHigh       37.94      (9.1%)       35.76      (7.0%)   -5.7% ( -20% -   11%)
                       OrHighMed       76.23      (9.0%)       73.41      (6.3%)   -3.7% ( -17% -   12%)
                    OrNotHighLow     1684.73      (4.6%)     1648.87      (6.6%)   -2.1% ( -12% -    9%)
                          IntNRQ       13.63      (4.0%)       13.49      (4.8%)   -1.0% (  -9% -    8%)
                      AndHighLow      731.68      (2.6%)      726.44      (3.6%)   -0.7% (  -6% -    5%)
                         Respell       61.24      (3.0%)       60.84      (3.7%)   -0.7% (  -7% -    6%)
                    HighSpanNear       22.89      (3.7%)       22.82      (4.0%)   -0.3% (  -7% -    7%)
                        HighTerm      136.93      (2.8%)      136.57      (3.1%)   -0.3% (  -5% -    5%)
                     MedSpanNear       72.54      (3.1%)       72.36      (3.5%)   -0.2% (  -6% -    6%)
                       MedPhrase       30.70      (1.9%)       30.63      (1.8%)   -0.2% (  -3% -    3%)
                      HighPhrase       35.13      (3.8%)       35.12      (3.5%)   -0.1% (  -7% -    7%)
                         MedTerm      184.28      (3.1%)      184.23      (2.5%)   -0.0% (  -5% -    5%)
                     AndHighHigh       16.74      (1.4%)       16.76      (1.4%)    0.1% (  -2% -    2%)
                     LowSpanNear       39.03      (1.8%)       39.08      (2.3%)    0.1% (  -3% -    4%)
                        Wildcard       43.57      (2.6%)       43.66      (2.9%)    0.2% (  -5% -    5%)
                      AndHighMed      178.28      (1.5%)      178.78      (2.1%)    0.3% (  -3% -    3%)
                    OrHighNotMed       71.53      (4.7%)       71.79      (2.8%)    0.4% (  -6% -    8%)
                    OrNotHighMed       79.22      (2.6%)       79.65      (2.0%)    0.5% (  -3% -    5%)
                   OrNotHighHigh       61.27      (3.0%)       61.61      (2.0%)    0.6% (  -4% -    5%)
                         LowTerm      818.90      (5.9%)      823.47      (4.3%)    0.6% (  -9% -   11%)
                         Prefix3      176.52      (2.9%)      177.57      (3.2%)    0.6% (  -5% -    6%)
                       LowPhrase      380.46      (3.4%)      383.13      (3.4%)    0.7% (  -5% -    7%)
                 MedSloppyPhrase      155.97      (3.5%)      157.16      (2.8%)    0.8% (  -5% -    7%)
                   OrHighNotHigh       45.73      (3.1%)       46.09      (1.9%)    0.8% (  -4% -    5%)
                 LowSloppyPhrase       65.95      (2.0%)       66.59      (1.6%)    1.0% (  -2% -    4%)
                    OrHighNotLow       97.93      (4.8%)       99.02      (2.4%)    1.1% (  -5% -    8%)
                          Fuzzy1       49.26      (6.6%)       50.06      (6.7%)    1.6% ( -10% -   16%)
                HighSloppyPhrase       24.74      (4.2%)       25.65      (5.8%)    3.7% (  -6% -   14%)
                       OrHighLow       84.42      (7.7%)      107.15      (8.4%)   26.9% (  10% -   46%)
        
        Show
        Adrien Grand added a comment - - edited I iterated on the previous patch in order to also optimize the case when all clauses return a non-null BulkScorer, but some windows of 2048 documents only contain matches for one of the sub scorers: in that case we can call the collector directly instead of going through a bitset and replaying. luceneutil on wikimedium10m shows a nice speedup for OrHighLow : TaskQPS baseline StdDev QPS patch StdDev Pct diff Fuzzy2 54.93 (13.3%) 51.19 (16.9%) -6.8% ( -32% - 26%) OrHighHigh 37.94 (9.1%) 35.76 (7.0%) -5.7% ( -20% - 11%) OrHighMed 76.23 (9.0%) 73.41 (6.3%) -3.7% ( -17% - 12%) OrNotHighLow 1684.73 (4.6%) 1648.87 (6.6%) -2.1% ( -12% - 9%) IntNRQ 13.63 (4.0%) 13.49 (4.8%) -1.0% ( -9% - 8%) AndHighLow 731.68 (2.6%) 726.44 (3.6%) -0.7% ( -6% - 5%) Respell 61.24 (3.0%) 60.84 (3.7%) -0.7% ( -7% - 6%) HighSpanNear 22.89 (3.7%) 22.82 (4.0%) -0.3% ( -7% - 7%) HighTerm 136.93 (2.8%) 136.57 (3.1%) -0.3% ( -5% - 5%) MedSpanNear 72.54 (3.1%) 72.36 (3.5%) -0.2% ( -6% - 6%) MedPhrase 30.70 (1.9%) 30.63 (1.8%) -0.2% ( -3% - 3%) HighPhrase 35.13 (3.8%) 35.12 (3.5%) -0.1% ( -7% - 7%) MedTerm 184.28 (3.1%) 184.23 (2.5%) -0.0% ( -5% - 5%) AndHighHigh 16.74 (1.4%) 16.76 (1.4%) 0.1% ( -2% - 2%) LowSpanNear 39.03 (1.8%) 39.08 (2.3%) 0.1% ( -3% - 4%) Wildcard 43.57 (2.6%) 43.66 (2.9%) 0.2% ( -5% - 5%) AndHighMed 178.28 (1.5%) 178.78 (2.1%) 0.3% ( -3% - 3%) OrHighNotMed 71.53 (4.7%) 71.79 (2.8%) 0.4% ( -6% - 8%) OrNotHighMed 79.22 (2.6%) 79.65 (2.0%) 0.5% ( -3% - 5%) OrNotHighHigh 61.27 (3.0%) 61.61 (2.0%) 0.6% ( -4% - 5%) LowTerm 818.90 (5.9%) 823.47 (4.3%) 0.6% ( -9% - 11%) Prefix3 176.52 (2.9%) 177.57 (3.2%) 0.6% ( -5% - 6%) LowPhrase 380.46 (3.4%) 383.13 (3.4%) 0.7% ( -5% - 7%) MedSloppyPhrase 155.97 (3.5%) 157.16 (2.8%) 0.8% ( -5% - 7%) OrHighNotHigh 45.73 (3.1%) 46.09 (1.9%) 0.8% ( -4% - 5%) LowSloppyPhrase 65.95 (2.0%) 66.59 (1.6%) 1.0% ( -2% - 4%) OrHighNotLow 97.93 (4.8%) 99.02 (2.4%) 1.1% ( -5% - 8%) Fuzzy1 49.26 (6.6%) 50.06 (6.7%) 1.6% ( -10% - 16%) HighSloppyPhrase 24.74 (4.2%) 25.65 (5.8%) 3.7% ( -6% - 14%) OrHighLow 84.42 (7.7%) 107.15 (8.4%) 26.9% ( 10% - 46%)
        Hide
        Alan Woodward added a comment -

        +1

        Another possible optimization here is to check the number of docs in the segment, and if it's below a certain size then don't use the bulk scorer. For example, big disjunctions run against a MemoryIndex currently allocate int[2048] for each node even though there's only a single doc in there.

        Show
        Alan Woodward added a comment - +1 Another possible optimization here is to check the number of docs in the segment, and if it's below a certain size then don't use the bulk scorer. For example, big disjunctions run against a MemoryIndex currently allocate int [2048] for each node even though there's only a single doc in there.
        Hide
        Adrien Grand added a comment -

        Another possible optimization here is to check the number of docs in the segment, and if it's below a certain size then don't use the bulk scorer.

        I like the idea and I was just going to try it out but I'm a bit concerned we would lose significant test coverage of BS1. So I'd rather experiment with this idea in a different issue where we also make sure to keep good coverage for BS1.

        Show
        Adrien Grand added a comment - Another possible optimization here is to check the number of docs in the segment, and if it's below a certain size then don't use the bulk scorer. I like the idea and I was just going to try it out but I'm a bit concerned we would lose significant test coverage of BS1. So I'd rather experiment with this idea in a different issue where we also make sure to keep good coverage for BS1.
        Hide
        ASF subversion and git services added a comment -

        Commit 1710591 from Adrien Grand in branch 'dev/trunk'
        [ https://svn.apache.org/r1710591 ]

        LUCENE-6850: Optimize BooleanScorer for sparse clauses.

        Show
        ASF subversion and git services added a comment - Commit 1710591 from Adrien Grand in branch 'dev/trunk' [ https://svn.apache.org/r1710591 ] LUCENE-6850 : Optimize BooleanScorer for sparse clauses.
        Hide
        ASF subversion and git services added a comment -

        Commit 1710604 from Adrien Grand in branch 'dev/branches/branch_5x'
        [ https://svn.apache.org/r1710604 ]

        LUCENE-6850: Optimize BooleanScorer for sparse clauses.

        Show
        ASF subversion and git services added a comment - Commit 1710604 from Adrien Grand in branch 'dev/branches/branch_5x' [ https://svn.apache.org/r1710604 ] LUCENE-6850 : Optimize BooleanScorer for sparse clauses.

          People

          • Assignee:
            Adrien Grand
            Reporter:
            Adrien Grand
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development