Uploaded image for project: 'Solr'
  1. Solr
  2. SOLR-12882

Eliminate excessive lambda allocation in FacetFieldProcessorByHashDV.collectValFirstPhase

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 7.5
    • Fix Version/s: 7.6
    • Component/s: Facet Module
    • Labels:
      None

      Description

      The FacetFieldProcessorByHashDV.collectValFirstPhase method looks like this:

      private void collectValFirstPhase(int segDoc, long val) throws IOException {
       int slot = table.add(val); // this can trigger a rehash
      
       // Our countAcc is virtual, so this is not needed:
       // countAcc.incrementCount(slot, 1);
      
      super.collectFirstPhase(segDoc, slot, slotNum ->
      
      { Comparable value = calc.bitsToValue(val); return new SlotContext(sf.getType().getFieldQuery(null, sf, calc.formatValue(value))); }
      
      );
      }
      

       

      For each value that is being iterated over there is a lambda allocation that is passed as the slotContext argument to the super.collectFirstPhase method. The lambda can be factored out such that there is only a single instance per FacetFieldProcessorByHashDV instance. 

      The only tradeoff being that the value needs to be looked up from the table in the lambda.  However looking the value up in the table is going to be less expensive than a memory allocation and also the slotContext lambda is only used in RelatednessAgg and not for any of the field faceting or metrics.

       

      private void collectValFirstPhase(int segDoc, long val) throws IOException {
        int slot = table.add(val); // this can trigger a rehash
      
        // Our countAcc is virtual, so this is not needed:
        // countAcc.incrementCount(slot, 1);
      
        super.collectFirstPhase(segDoc, slot, slotContext);
      }
      
      /**
       * SlotContext to use during all {@link SlotAcc} collection.
       *
       * This avoids a memory allocation for each invocation of collectValFirstPhase.
       */
      private IntFunction<SlotContext> slotContext = (slotNum) -> {
        long val = table.vals[slotNum];
        Comparable value = calc.bitsToValue(val);
        return new SlotContext(sf.getType().getFieldQuery(null, sf, calc.formatValue(value)));
      };
      

       

      FacetFieldProcessorByArray already follows this same pattern

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                dsmiley David Smiley
                Reporter:
                tpunder Tim Underwood
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 0.5h
                  0.5h