Skip to content

Improve benchmark accuracy - #31

Merged
timohanke merged 3 commits into
mainfrom
benchmarks
Jan 26, 2026
Merged

Improve benchmark accuracy#31
timohanke merged 3 commits into
mainfrom
benchmarks

Conversation

@timohanke

@timohanke timohanke commented Jan 26, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • Refactor

    • Reworked benchmark system to a versioned schema with a unified run interface and data-driven configurations, improving consistency.
  • New Features

    • Enhanced benchmark input generation and exercise coverage to improve measurement accuracy.
  • Chores

    • Bumped package and dev dependency versions, added a toolchain entry, and updated the changelog.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 26, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Refactored two benchmark modules to a versioned BenchV1 API with a formal Schema and an indexed run(ri, ci) dispatcher; added public init() returning BenchV1. Also updated package metadata and bumped a dev dependency.

Changes

Cohort / File(s) Summary
Benchmark Architecture Refactor
bench/vector-sort.bench.mo, bench/vector.bench.mo
Added Schema type and BenchV1 class; replaced prior bench instance creation with init() : BenchV1. Rewrote runners to use run(ri, ci) indexing, introduced structured input generation (arrays/buffers/vectors), and added placeholder accessors to satisfy type contracts.
Package & Changelog
mops.toml, CHANGELOG.md
Bumped package version and dev-dependency (bench 2.0.0 → 2.0.1) and added changelog entry for 0.4.5.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant BenchV1 as BenchV1 (init)
  participant Dispatcher as run(ri,ci)
  participant VectorSort as Vector.sort
  participant BufferSort as Buffer.sort
  participant ArraySort as Array.sort

  Caller->>BenchV1: init() -> BenchV1(schema, run)
  Caller->>BenchV1: runCell(ri, ci)
  BenchV1->>Dispatcher: run(ri, ci)
  alt ri selects vector path
    Dispatcher->>VectorSort: sort(vectorInput[ri][ci])
    VectorSort-->>Dispatcher: sorted
  else ri selects buffer path
    Dispatcher->>BufferSort: sort(bufferInput[ri][ci])
    BufferSort-->>Dispatcher: sorted
  else ri selects array path
    Dispatcher->>ArraySort: sort(arrayInput[ri][ci])
    ArraySort-->>Dispatcher: sorted
  end
  Dispatcher-->>Caller: done
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hop and code a schema bright,

BenchV1 guards the benchmark light,
Indices guide each sorting race,
Buffers, vectors, arrays in place,
A rabbit cheers this tidy chase 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly reflects the main objective of the pull request, which is to improve benchmark accuracy by refactoring the benchmark infrastructure to use a versioned BenchV1 class with formal Schema types and a data-driven approach.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@bench/vector-sort.bench.mo`:
- Around line 72-90: The benchmark mutates shared inputs because run calls
Vector.sort and buf.sort on precomputed vectorInput and bufferInput; change run
to operate on clones so each iteration sorts fresh data: inside func run(ri, ci)
create local clones of vectorInput[ri/3][ci] and bufferInput[ri/3][ci] (e.g.
convert to an intermediate Array and then back or use the library's
copy/fromArray/toArray helpers) and call Vector.sort and buf.sort on those
clones; similarly clone arrayInput before calling Array.sort (or use a
non-mutating sort helper) so vectorInput, bufferInput, and arrayInput remain
unchanged across runs.
🧹 Nitpick comments (1)
bench/vector-sort.bench.mo (1)

10-29: Consider extracting shared Schema and BenchV1 definitions.

The Schema type and BenchV1 class are duplicated between vector.bench.mo and vector-sort.bench.mo. If the bench framework allows, consider extracting these to a shared module to reduce duplication.

Comment on lines +72 to +90
let bufferInput = Array.map(arrayInput, func x = Array.map(x, func y = Buffer.fromArray<Nat>(y)));
let vectorInput = Array.map(arrayInput, func x = Array.map(x, func y = Vector.fromArray<Nat>(y)));

routines[ci * rows.size() + ri]();
}
);
func run(ri : Nat, ci : Nat) {
switch (ri % 3) {
case (0) {
let vec = vectorInput[ri / 3][ci];
Vector.sort(vec, Nat.compare);
};
case (1) {
let buf = bufferInput[ri / 3][ci];
buf.sort(Nat.compare);
};
case (2) {
let arr = arrayInput[ri / 3][ci];
ignore Array.sort<Nat>(arr, Nat.compare);
};
case (_) Prim.trap("Can never happen");
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Potential issue: In-place sorting mutates shared input data.

vectorInput and bufferInput are created once during init(), but Vector.sort and buf.sort mutate them in-place. After the first benchmark run, these collections will already be sorted, so subsequent iterations (if the framework runs multiple) will measure sorting already-sorted data rather than the original input.

If accurate benchmarking of sorting performance is the goal, consider one of:

  1. Clone the input before sorting each time
  2. Regenerate input for each benchmark iteration
  3. Document that this measures single-run performance only
🤖 Prompt for AI Agents
In `@bench/vector-sort.bench.mo` around lines 72 - 90, The benchmark mutates
shared inputs because run calls Vector.sort and buf.sort on precomputed
vectorInput and bufferInput; change run to operate on clones so each iteration
sorts fresh data: inside func run(ri, ci) create local clones of
vectorInput[ri/3][ci] and bufferInput[ri/3][ci] (e.g. convert to an intermediate
Array and then back or use the library's copy/fromArray/toArray helpers) and
call Vector.sort and buf.sort on those clones; similarly clone arrayInput before
calling Array.sort (or use a non-mutating sort helper) so vectorInput,
bufferInput, and arrayInput remain unchanged across runs.

@timohanke
timohanke merged commit cd9c38a into main Jan 26, 2026
1 of 2 checks passed
@timohanke
timohanke deleted the benchmarks branch January 26, 2026 10:50
@coderabbitai coderabbitai Bot mentioned this pull request Mar 18, 2026
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.

1 participant