Skip to content

Benchmark examples - #1442

Open
dalonsoa wants to merge 10 commits into
mainfrom
benchmark_examples
Open

Benchmark examples#1442
dalonsoa wants to merge 10 commits into
mainfrom
benchmark_examples

Conversation

@dalonsoa

@dalonsoa dalonsoa commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Description

Add the benchmarking of the examples using Criterion. Some bits of the code had to be skip using features, as they are meant to be run only once and when doing benchmarking, they were run many times.

To run the example benchmarks do cargo bench --features bench --bench examples. The --features bench is what skips the bits of the code we don't want.

When doing this, you will get something like (you will see the comparison only if run more than once, so it has something to compare with).

Benchmarking circularity example: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 19.1s, or reduce sample count to 20.
circularity example     time:   [196.48 ms 198.58 ms 200.73 ms]
                        change: [+1.0287% +2.4241% +3.6992%] (p = 0.00 < 0.05)
                        Performance has regressed.

Benchmarking missing_commodity example: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 10.1s, or reduce sample count to 40.
missing_commodity example
                        time:   [103.85 ms 104.95 ms 106.03 ms]
                        change: [+4.7057% +5.7676% +6.8415%] (p = 0.00 < 0.05)
                        Performance has regressed.

Benchmarking muse1_default example: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 6.8s, or reduce sample count to 70.
muse1_default example   time:   [67.303 ms 67.915 ms 68.560 ms]
                        change: [−6.2344% −5.2121% −4.1841%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 19 outliers among 100 measurements (19.00%)
  19 (19.00%) high mild

Benchmarking simple example: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 5.3s, or reduce sample count to 90.
simple example          time:   [52.264 ms 52.839 ms 53.423 ms]
                        change: [−1.7339% −0.3424% +1.1195%] (p = 0.64 > 0.05)
                        No change in performance detected.

Benchmarking two_outputs example: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 20.7s, or reduce sample count to 20.
two_outputs example     time:   [196.58 ms 198.26 ms 199.90 ms]
                        change: [−1.7246% −0.4640% +0.6560%] (p = 0.43 > 0.05)
                        No change in performance detected.

Benchmarking two_regions example: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 12.7s, or reduce sample count to 30.
two_regions example     time:   [119.93 ms 121.06 ms 122.22 ms]
                        change: [−1.0131% +0.2356% +1.4263%] (p = 0.70 > 0.05)
                        No change in performance detected.

I need to tweak the settings to remove the warnings and play a bit more with it - that's why this is a draft -, but this is the basic idea that we can roll to other critical functions that we want to optimise in the future.

It also produces nice reports:

Screenshot from 2026-07-28 10-41-53

Fixes #1443

Type of change

  • Bug fix (non-breaking change to fix an issue)
  • New feature (non-breaking change to add functionality)
  • Refactoring (non-breaking, non-functional change to improve maintainability)
  • Optimization (non-breaking change to speed up the code)
  • Breaking change (whatever its nature)
  • Documentation (improve or add documentation)

Key checklist

  • All tests pass: $ cargo test
  • The documentation builds and looks OK: $ cargo doc
  • Update release notes for the latest release if this PR adds a new feature or fixes a bug
    present in the previous release

Further checks

  • Code is commented, particularly in hard-to-understand areas
  • Tests added that prove fix is effective or that feature works

@dalonsoa
dalonsoa requested review from alexdewar and tsmbland July 28, 2026 09:35
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 40.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.65%. Comparing base (80b2c11) to head (4f63d24).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/cli.rs 50.00% 1 Missing and 1 partial ⚠️
src/model/parameters.rs 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1442      +/-   ##
==========================================
- Coverage   89.67%   89.65%   -0.02%     
==========================================
  Files          60       60              
  Lines        8565     8568       +3     
  Branches     8565     8568       +3     
==========================================
+ Hits         7681     7682       +1     
- Misses        561      562       +1     
- Partials      323      324       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dalonsoa
dalonsoa marked this pull request as ready for review July 28, 2026 10:22
Copilot AI review requested due to automatic review settings July 28, 2026 10:22
@dalonsoa

Copy link
Copy Markdown
Collaborator Author

After increasing the noise level and reducing the sample size to what, I think, are more sensible values for the examples - other functions might benefit from different values - I get the following, which seems nice. So this is ready to review:

example_run/circularity example
                        time:   [193.12 ms 196.40 ms 199.73 ms]
                        change: [−5.0036% −3.0979% −1.0469%] (p = 0.01 < 0.05)
                        Change within noise threshold.
example_run/missing_commodity example
                        time:   [99.844 ms 101.25 ms 102.92 ms]
                        change: [−2.0078% −0.2362% +1.8626%] (p = 0.82 > 0.05)
                        No change in performance detected.
Found 3 outliers among 20 measurements (15.00%)
  2 (10.00%) high mild
  1 (5.00%) high severe
example_run/muse1_default example
                        time:   [71.486 ms 72.036 ms 72.458 ms]
                        change: [+1.9784% +3.2002% +4.4315%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 3 outliers among 20 measurements (15.00%)
  1 (5.00%) low severe
  1 (5.00%) low mild
  1 (5.00%) high mild
example_run/simple example
                        time:   [51.410 ms 52.211 ms 53.059 ms]
                        change: [−5.8471% −4.1450% −2.3666%] (p = 0.00 < 0.05)
                        Change within noise threshold.
example_run/two_outputs example
                        time:   [195.25 ms 198.60 ms 201.79 ms]
                        change: [−0.1796% +1.8967% +3.7674%] (p = 0.08 > 0.05)
                        No change in performance detected.
example_run/two_regions example
                        time:   [120.26 ms 121.63 ms 123.17 ms]
                        change: [−6.2361% −5.0315% −3.7469%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 2 outliers among 20 measurements (10.00%)
  2 (10.00%) high mild

Copilot AI left a comment

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.

Pull request overview

Adds Criterion-based benchmarking for the built-in CLI examples, introducing a bench feature to disable/relax certain one-time initialisation paths so examples can be executed repeatedly during benchmarking.

Changes:

  • Add benches/examples.rs Criterion benchmark that runs each built-in example via the CLI entrypoint.
  • Add a bench Cargo feature and [[bench]] target configuration, plus Criterion as a dev-dependency.
  • Gate a couple of “initialise once” behaviours behind cfg!(feature = "bench") to support repeated runs (logging init + dangerous-options global flag).

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/model/parameters.rs Allows re-setting the dangerous-options OnceLock in bench builds (same-value only), to support repeated model loads in one process.
src/cli.rs Skips logger initialisation in bench builds to avoid log I/O affecting benchmark runs.
Cargo.toml Adds Criterion dev-dependency, declares examples bench target, and introduces bench feature.
Cargo.lock Locks Criterion and transitive dependencies.
benches/examples.rs Implements Criterion benchmarks for each example using handle_example_run_command.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread benches/examples.rs
Comment thread benches/examples.rs
dalonsoa and others added 3 commits July 28, 2026 11:30
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@dalonsoa
dalonsoa force-pushed the benchmark_examples branch from ed329da to ee7c648 Compare July 28, 2026 11:47
@dalonsoa
dalonsoa requested a review from dc2917 July 28, 2026 11:56
@tsmbland

Copy link
Copy Markdown
Collaborator

Looks promising! Could you add something to the dev guide to explain how to use this, including how to generate reports?

@alexdewar

Copy link
Copy Markdown
Member

Looks really neat! I like the plots. Longer term, maybe we could even think about doing automated performance regression testing, so we'd get notified on PRs about it the same way we do about code coverage.

It's slightly annoying that you have to enable an extra feature to detect whether it's being benchmarked, but the alternative suggestions I got from AI didn't work 🤷. Not the most important thing though.

@dalonsoa

dalonsoa commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator Author

Check this: https://github.com/benchmark-action/github-action-benchmark

It supports cargo bench out of the box, so it might be super straight forward to implement. But that's probably for a separate PR.

@dalonsoa

Copy link
Copy Markdown
Collaborator Author

@tsmbland @alexdewar docs added, so this is ready for re-review. It would be good if your could check this locally, as well, to make sure all works as expected.

@tsmbland

Copy link
Copy Markdown
Collaborator

@dalonsoa How do I see the comparison in the report? I ran cargo bench --features bench twice and I'm seeing a comparison in the terminal, but it's not showing in the report like the above screenshot

@tsmbland

Copy link
Copy Markdown
Collaborator

@dalonsoa How do I see the comparison in the report? I ran cargo bench --features bench twice and I'm seeing a comparison in the terminal, but it's not showing in the report like the above screenshot

Actually don't worry! Just cleared target/criterion and tried again and it works now. I think there was some outdated stuff in there messing things up

@tsmbland tsmbland 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.

This is really neat! I like how it has to warm up, like an old TV (do we need it to warm up before every example though?)

Way beyond the scope of this PR, but it would be nice to have a shorthand way to compare performance against main, without having to manually switch branches and run the benchmarking on each branch.

Also, some way to get running times for investment vs dispatch into the reports?

Comment thread docs/developer_guide/coding.md Outdated
Comment thread benches/examples.rs
Co-authored-by: Tom Bland <t.bland@imperial.ac.uk>
@dalonsoa

Copy link
Copy Markdown
Collaborator Author

I've no idea why we need the warm up time, but I'm sure that time can be tweaked.

Open an issue about the comparison with main, so we don't forget and can tackle it in the future. It's a great idea.

@dc2917 dc2917 left a comment

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 all looks good to me overall.

It does seems slightly odd that it still tries to run the test suite, just to report that they were all ignored.

It also seems odd that successive runs (i.e. no changes to the code) report performance increases/decreases - perhaps it's worth increasing the threshold?

@dalonsoa

Copy link
Copy Markdown
Collaborator Author

It seems that there is a bit of a mess between benches and tests. I'm not entirely sure what should run with each command. See, for example:

rust-lang/cargo#6454

On the last bit, I guess it might depend on what is being run in the computer, in addition to the benches. I set a 5%, but it might be we want a higher value. Don't know what the expected variability might be just from noise.

@dc2917

dc2917 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

It seems that there is a bit of a mess between benches and tests. I'm not entirely sure what should run with each command. See, for example:

rust-lang/cargo#6454

Ah OK, yeah, clearly a known issue. It's only a minor thing anyway.

On the last bit, I guess it might depend on what is being run in the computer, in addition to the benches. I set a 5%, but it might be we want a higher value. Don't know what the expected variability might be just from noise.

Yes, I think you're right (first time I ran the benchmarks, compilation crashed a bunch of my running programs, so there wasn't much running during the tests; second time, I'd opened browser and Teams etc back up). So yeah, 5% seems entirely reasonable.
I guess this is another reason for automated benchmarking as Alex mentioned, which might have a more stable/controlled environment.

@dc2917
dc2917 self-requested a review July 30, 2026 13:12

@alexdewar alexdewar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

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.

Add benchmarks for examples

5 participants