Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable comparing main facets module agains sandbox facets implementation #325

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

epotyom
Copy link

@epotyom epotyom commented Jan 7, 2025

Auxiliary changes:

  • SearchTask#getFacetResultsMsec now includes time to run #search, because in the sandbox module we can't measure search and facet compute times separately. But it might be the right thing to do anyway, as otherwise we don't account for time spent to build doc ID sets in FacetsCollector?
  • Enable attaching a context to Task, to be able to use different implementations for the same task and Lucene code in baseline/candidate
  • Fix facets result overlap check: in python SearchTask's equals and hash methods compare facets requests, not results
  • Added facetsWikimediumAll config that contains all taxonomy facets tasks from wikimediumall

Command to run:

python src/python/localrunFacets.py -source facetsWikimediumAll

Results on my laptop

Report after iter 19:

                            TaskQPS classic_facets      StdDevQPS sandbox_facets      StdDev                Pct diff p-value
     BrowseRandomLabelTaxoFacets        5.99      (6.0%)        2.64      (1.6%)  -55.9% ( -59% -  -51%) 0.000
                        PKLookup      297.27      (5.8%)      251.45      (4.9%)  -15.4% ( -24% -   -5%) 0.000
         AndHighMedDayTaxoFacets      154.40      (3.2%)      153.00     (14.8%)   -0.9% ( -18% -   17%) 0.788
        AndHighHighDayTaxoFacets       13.13      (3.4%)       13.04     (11.7%)   -0.7% ( -15% -   14%) 0.792
          OrHighMedDayTaxoFacets       16.27      (5.5%)       19.52     (20.0%)   20.0% (  -5% -   48%) 0.000
       BrowseDayOfYearTaxoFacets        6.52      (7.7%)        9.30     (12.9%)   42.8% (  20% -   68%) 0.000
            BrowseDateTaxoFacets        6.48      (7.6%)        9.68     (13.9%)   49.3% (  25% -   76%) 0.000
           BrowseMonthTaxoFacets        6.21      (6.9%)        9.38     (15.1%)   51.0% (  27% -   78%) 0.000
            MedTermDayTaxoFacets       38.03      (3.9%)       71.68     (25.3%)   88.5% (  57% -  122%) 0.000

I'll look into why there is regression for BrowseRandomLabelTaxoFacets and PKLookup

@epotyom
Copy link
Author

epotyom commented Jan 9, 2025

There is BrowseRandomLabelTaxoFacets regression because RandomLabel.taxonomy field is the one that uses most of the sidecar taxonomy index, and it seems to be the only field for which dense counting (in array) pays off; total array (and taxon index) size is 1559911, and when counting is done, only 3422 (0.2%) elements are still zeros.

We can think about implementing dense counting for the sandbox facet module, but it looks like a rare use case to me - not only we need a field with large number of unique values, but it also needs to be a MatchAllDocsQuery.

In any case, seems like the result is expected. Looking into PKLookup regression now.

Copy link
Collaborator

@stefanvodita stefanvodita left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SearchTask#getFacetResultsMsec now includes time to run #search

Will that change results we were already reporting? Just good to know.

import org.apache.lucene.facet.Facets;
import org.apache.lucene.facet.FacetsCollector;
import org.apache.lucene.facet.FacetsCollectorManager;
import org.apache.lucene.facet.*;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want to avoid the wildcard import.
(Same below)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I think my Intellij folded it, I'll change

// TODO: support sort, filter too!!
// TODO: support other facet methods
List<TaskParser.TaskBuilder.FacetTask> classicFacetRequests = new ArrayList<>();
List<TaskParser.TaskBuilder.FacetTask> sandboxFacetRequests = new ArrayList<>();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're starting to spread this temporary name. It would have been great to converge on apache/lucene#13965 before, but I don't know that we want to wait now.

Copy link
Owner

@mikemccand mikemccand Feb 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I say @epotyom and @Shradha26 should simply pick a name, now, and run with it, here :) Surprise us!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I'm thinking about it is that new classes can be moved to the existing facets module once we believe they are mature enough. I don't think these classes belong in an independent module, they depend on a lot of things from the facets module, e.g. indexing time functionality or drill sideways. I promise to clean up and get rid of all mentions of "sandbox" once we do it, or, if decided otherwise, once we create a separate module for it. What do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good point that the new classes may become part of the facets module.
In this PR though, we're using "sanbox" as a contrast to "classic". Can we name it something generic, such as "matchTime", or are we not that detached from the particular implementation?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have a point. How about postCollectionFacets for classic VS directCollectionFacets or directFacets for sandbox? Or docIdSetFacets VS directFacets?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like postCollectionFacets. Can we pair it with duringCollectionFacets, withCollectionFacets, or collectionFacets?

public enum FacetMode {
UNDEFINED,
CLASSIC,
SANDBOX, // TODO: better names?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

@@ -1193,7 +1195,9 @@ def runSimpleSearchBench(self, iter, id, c,
command += [f'-XX:StartFlightRecording=dumponexit=true,maxsize=250M,settings={constants.BENCH_BASE_DIR}/src/python/profiling.jfc' +
f',filename={constants.LOGS_DIR}/bench-search-{id}-{c.name}-{iter}.jfr',
'-XX:+UnlockDiagnosticVMOptions',
'-XX:+DebugNonSafepoints']
'-XX:+DebugNonSafepoints',
# '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:7891'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you leave this in accidentally?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was intentional, it makes it easy to enable remote debug - just uncomment this line. Maybe I should add a comment. Do you think it's better to remove?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I don't mind leaving it in if you found it helpful for quick debugging.

import competition
import os

# Script to compare performance of sandbox and main facets modules
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention this file somewhere visible, maybe in the README?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, will do in the next revision.

@@ -0,0 +1,40 @@
package perf;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs copyright header?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@mikemccand
Copy link
Owner

  • otherwise we don't account for time spent to build doc ID sets in FacetsCollector?

+1 -- good catch!

@epotyom
Copy link
Author

epotyom commented Feb 10, 2025

Thank you for reviewing @stefanvodita !

SearchTask#getFacetResultsMsec now includes time to run #search

Will that change results we were already reporting? Just good to know.

Yeah, but TBH I can't find where we report getFacetResultsMsec. We print it to log, and then benchUtil reads it. Not sure what happens to it next. Maybe it is used in a different repo?

I believe that QPS metrics reported by localrun.py are not going to change.

epotyom and others added 5 commits February 10, 2025 23:04
Command to run:

python src/python/localrunFacets.py -source facetsWikimediumAll

Auxiliary changes:
- Enable attaching context to a Task, to be able to use different implementations for the same task and Lucene code in baseline/candidate
- Fix facets result overlap check: in python SearchTask's equals and hash methods to compare facets request, not results
- Added facetsWikimediumAll config that contains all taxonomy facets tasks from wikimediumall
Copy link
Collaborator

@stefanvodita stefanvodita left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few more small comments. Thank you for making the changes, great to see this change coming along!


There are currently two facets implementations - one that first collects document IDs and then computes facets in a separate phase, and a new implementation that computes facets during collection.

To compare performance for the two implementations run
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add details about what exactly gets compared? For example, you had a comment about only taxonomy facets being compared I think.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, added.

// for MatchAllDocsQuery to make collection for all docs in the index faster?
Map<String, CountFacetRecorder> indexFieldToRecorder = new HashMap<>();
List<CollectorManager<? extends Collector, ?>> collectorManagers = new ArrayList<>();
// First collector manager in the list is to collect hits, but not for if MatchAllDocsQuery
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we state this more clearly?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded!

if (request.dimension().startsWith("range:")) {
throw new AssertionError("fix me!");
} else if (request.dimension().endsWith(".taxonomy")) {
//if (true) throw new RuntimeException("fix me! " + request.dimension() + "; " + state.facetsConfig.getDimConfig(request.dimension()).indexFieldName);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgotten commented code?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed, sorry for the mess!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants