Skip to content

Add percent-change histogram to metrics diff report#4247

Draft
arnaud-lacurie wants to merge 4 commits into
FoundationDB:mainfrom
arnaud-lacurie:metrics-histogram
Draft

Add percent-change histogram to metrics diff report#4247
arnaud-lacurie wants to merge 4 commits into
FoundationDB:mainfrom
arnaud-lacurie:metrics-histogram

Conversation

@arnaud-lacurie

Copy link
Copy Markdown
Collaborator

Appends a text histogram of the % change distribution to each field's stats block in the metrics diff report.

  • MetricsStatistics: collect percent diffs per field in Builder, expose as sorted FieldStatistics.sortedPercentDiffs
  • MetricsDiffAnalyzer: render a 2%-wide bin bar chart after each field summary; guard against lo == hi edge case (all values identical on a bin boundary)

@arnaud-lacurie arnaud-lacurie added the build improvement Improvement to the build system label Jun 1, 2026
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

📊 Metrics Diff Analysis Report

Summary

  • New queries: 0
  • Dropped queries: 0
  • Plan changed + metrics changed: 0
  • Plan unchanged + metrics changed: 16
ℹ️ About this analysis

This automated analysis compares query planner metrics between the base branch and this PR. It categorizes changes into:

  • New queries: Queries added in this PR
  • Dropped queries: Queries removed in this PR. These should be reviewed to ensure we are not losing coverage.
  • Plan changed + metrics changed: The query plan has changed along with planner metrics.
  • Metrics only changed: Same plan but different metrics

The last category in particular may indicate planner regressions that should be investigated.

Only Metrics Changed

These queries experienced only metrics changes without any plan changes. If these metrics have substantially changed,
then a planner change has been made which affects planner performance but does not correlate with any new outcomes,
which could indicate a regression.

Total: 16 queries

Statistical Summary (Only Metrics Changed)

task_count:

  • Average change: +500.0
  • Average regression: +500.0
  • Median change: +500
  • Median regression: +500
  • Standard deviation: 0.0
  • Standard deviation of regressions: 0.0
  • Range: +500 to +500
  • Range of regressions: +500 to +500
  • Queries changed: 16
  • Queries regressed: 16

There were no queries with significant regressions detected.

Minor Changes (Only Metrics Changed)

In addition, there were 16 queries with minor changes.

final double binWidth = 2.0;
final int barWidth = 30;
final double lo = Math.floor(sortedPercentDiffs.get(0) / binWidth) * binWidth;
double hi = Math.ceil(sortedPercentDiffs.get(sortedPercentDiffs.size() - 1) / binWidth) * binWidth;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
double hi = Math.ceil(sortedPercentDiffs.get(sortedPercentDiffs.size() - 1) / binWidth) * binWidth;
final double hi = (Math.floor(sortedPercentDiffs.get(sortedPercentDiffs.size() - 1) / binWidth) + 1) * binWidth;

That way, the if (hi <= lo) check below is not necessary.

final var standardDeviation = Math.sqrt(variance);

builder.put(fieldName, new FieldStatistics(values, mean, standardDeviation));
final List<Double> sortedPcts = percentDifferences.getOrDefault(fieldName, ImmutableList.of());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Rather name it just pcts instead of sortedPcts. At this point it is not actually sorted yet!

Comment on lines +555 to +556
final double binWidth = 2.0;
final int barWidth = 30;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Consider turning these into actual arguments (or maybe private static constants)?

There’s a comment further down that mentions BIN_WIDTH. That would make more sense if there were an actual private static BIN_WIDTH.


report.append(String.format(Locale.ROOT, "`%s` %% change distribution (%d queries, bin = 2%%):%n%n", fieldName, sortedPercentDiffs.size()));
report.append("```\n");
report.append(String.format(Locale.ROOT, "%14s %-30s n%n", "Range", ""));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there an (easy) way to avoid hard-coding the %14s width here?

}
}

private void appendHistogram(@Nonnull final StringBuilder report,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks like it can be a static method.

It’s a matter of taste, but I would consider splitting off two more submethods:

  1. The part that computes the bins from sortedPercentDiffs.
  2. The part that formats a String from the bins.

These could then be understood and (hypothetically) unit-tested independently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build improvement Improvement to the build system

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants