Skip to content

complexity: filter skipped runs and validate sample count in ComputeBigO - #2330

Open
jdymitarai wants to merge 1 commit into
google:mainfrom
jdymitarai:fix-complexity-skip-and-divzero
Open

jdymitarai wants to merge 1 commit into
google:mainfrom
jdymitarai:fix-complexity-skip-and-divzero

Conversation

@jdymitarai

Copy link
Copy Markdown
Contributor

When benchmark runs within a family are skipped via SkipWithError or SkipWithMessage, their iterations count evaluates to zero, causing ComputeBigO to divide accumulated time by zero and produce NaN values across BigO and RMS outputs. Furthermore, unlike ComputeStats which cleanly filters out non-successful runs, ComputeBigO previously processed all report entries unconditionally and accessed reports[0] for metadata even if the first run had failed or been skipped. Additionally, when all complexity points evaluate to zero under least-squares fitting (such as log2(1) under oLogN) or when non-positive sizes are passed, the fitting denominator vanishes and yields invalid floating-point values.

This change aligns ComputeBigO with the successful-run filtering pattern established in ComputeStats, requiring at least two valid runs with non-zero iterations before calculating BigO aggregates and utilizing the first successful run for reporter metadata. In FittingCurve and MinimalLeastSq, non-positive complexity sizes for logarithmic curves and zero-valued least-squares denominators are defensively guarded to return zero coefficients rather than generating division-by-zero anomalies or propagating NaNs. Unit tests in statistics_gtest verify that skipped runs are ignored and zero-denominator regressions are properly handled.

Comment thread src/complexity.cc

} // end namespace

std::vector<BenchmarkReporter::Run> ComputeBigO(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Changes to this function look good.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Forward progress suggestion:
I'd propose to keep only the changes to this function in this PR,
and deal with the rest in another PR.
(I'm not yet convinced about those other changes.)

Comment thread src/complexity.cc Outdated
// Calculate complexity.
result.coef = sigma_time_gn / sigma_gn_squared;
// Calculate complexity. Guard against division by zero if all fitting points evaluate to zero.
result.coef = (std::fpclassify(sigma_gn_squared) == FP_ZERO || sigma_gn_squared <= 0.0)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why std::fpclassify()?

Comment thread src/complexity.cc Outdated
Comment on lines +123 to +124
result.rms = (std::fpclassify(mean) == FP_ZERO ||
std::fpclassify(sigma_gn_squared) == FP_ZERO)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same, why not just <= ?

Comment thread src/complexity.cc Outdated
for (const auto& fit : fit_curves) {
LeastSq current_fit = MinimalLeastSq(n, time, FittingCurve(fit));
if (current_fit.rms < best_fit.rms) {
if (!std::isnan(current_fit.rms) && current_fit.rms < best_fit.rms) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

But can we end up with a NAN here after all?

Comment thread src/complexity.cc
return n <= 0 ? 0.0
: static_cast<double>(n) *
std::log2(static_cast<double>(n));
};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I do not understand. How n can be 0 here?

@jdymitarai
jdymitarai force-pushed the fix-complexity-skip-and-divzero branch from 6971dcc to 12dbc7e Compare October 11, 2026 05:49
@jdymitarai jdymitarai changed the title complexity: guard against division by zero and filter skipped runs in ComputeBigO complexity: filter skipped runs and validate sample count in ComputeBigO Oct 11, 2026
@jdymitarai

Copy link
Copy Markdown
Contributor Author

Thanks for the review and the suggestion! I have updated the branch to isolate the changes strictly to ComputeBigO and its unit test for filtering skipped runs, reverting the unrelated adjustments to FittingCurve and MinimalLeastSq. Ready for another look.

@jdymitarai

Copy link
Copy Markdown
Contributor Author

@googlebot I signed it!

@jdymitarai
jdymitarai force-pushed the fix-complexity-skip-and-divzero branch from 12dbc7e to 855b389 Compare October 11, 2026 10:14
Comment thread test/statistics_gtest.cc
0.32888184094918121, 1e-15);
}

TEST(ComplexityTest, ComputeBigOFiltersSkippedRuns) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why does this need to be a gtest and not a usual output test?

@LebedevRI LebedevRI left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LG

This branch has not been deployed

No deployments
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.

2 participants