Skip to content

chore: bump alloc_tracker from 0.6.0 to 0.7.0 - #568

Open
dependabot[bot] wants to merge 11 commits into
mainfrom
dependabot/cargo/alloc_tracker-0.7.0
Open

chore: bump alloc_tracker from 0.6.0 to 0.7.0#568
dependabot[bot] wants to merge 11 commits into
mainfrom
dependabot/cargo/alloc_tracker-0.7.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jul 13, 2026

Copy link
Copy Markdown
Contributor

Bumps alloc_tracker from 0.6.0 to 0.7.0.

Commits
  • bee10e4 Release
  • 4394bd9 Simplify tracker span API and condense docs (#342)
  • 6935825 Make cargo-bench-history collect tests hermetic against CARGO_TARGET_DIR (#341)
  • d40a479 Pin Cargo tool versions in constants.env; bump gungraun to 0.19.3 (#340)
  • e630a6f Align install-tools with CI, remove divergent tooling paths (#339)
  • c646b29 Verify cargo-semver-checks is operational
  • 64859ce Azurite optional
  • b104e4b Document measurement overhead in alloc_tracker, align all_the_time (#338)
  • b8cf5c2 Attach discriminant-set filter flags to analyze reports (#337)
  • 0437b1e Relax workflow timeouts for cold-cache setup-environment (#336)
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [alloc_tracker](https://github.com/folo-rs/folo) from 0.6.0 to 0.7.0.
- [Release notes](https://github.com/folo-rs/folo/releases)
- [Changelog](https://github.com/folo-rs/folo/blob/main/docs/release-automation.md)
- [Commits](folo-rs/folo@alloc_tracker-v0.6.0...alloc_tracker-v0.7.0)

---
updated-dependencies:
- dependency-name: alloc_tracker
  dependency-version: 0.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file rust Pull requests that update rust code labels Jul 13, 2026
Copilot AI review requested due to automatic review settings July 13, 2026 07:08
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file rust Pull requests that update rust code labels Jul 13, 2026

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.

Copilot can't review bot-authored pull requests automatically. A user with Copilot access can request a review manually.

@Vaiz

Vaiz commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@copilot, do a proper upgrade

Copilot AI review requested due to automatic review settings July 13, 2026 09:00
@dependabot
dependabot Bot removed the request for review from Copilot July 13, 2026 09:00

Copilot AI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@copilot, do a proper upgrade

Addressed in 05c5872.

Comment thread crates/multitude/Cargo.toml Outdated
Copilot AI review requested due to automatic review settings July 13, 2026 09:05
@dependabot
dependabot Bot removed the request for review from Copilot July 13, 2026 09:05
Copilot finished work on behalf of Vaiz July 13, 2026 09:06
@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.8%. Comparing base (c1df038) to head (ab4791f).

❌ Your project check has failed because the head coverage (91.8%) is below the target coverage (100.0%). You can increase the head coverage or adjust the target coverage.

❗ There is a different number of reports uploaded between BASE (c1df038) and HEAD (ab4791f). Click for more details.

HEAD has 3 uploads less than BASE
Flag BASE (c1df038) HEAD (ab4791f)
3 0
Additional details and impacted files
@@            Coverage Diff            @@
##             main    #568      +/-   ##
=========================================
- Coverage   100.0%   91.8%    -8.2%     
=========================================
  Files         470     430      -40     
  Lines       45251   36326    -8925     
=========================================
- Hits        45251   33365   -11886     
- Misses          0    2961    +2961     
Flag Coverage Δ
linux 92.1% <ø> (?)
linux-arm 91.8% <ø> (?)
windows 91.8% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.

Comment thread crates/bytesbuf/benches/buf.rs Outdated
BytesBuf::new,
|buf| {
let _span = allocs_op.measure_thread();
let _span = allocs_op.measure_thread().iterations(1);

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.

The documentation of alloc_tracker specifically mentions that iterations should be batched. Forcing us to call .iterations(N) is the breaking change, to help highlight when we are doing iterations one by one, which includes huge (relatively) measurement overhead.

The proper upgrade would also fix the pattern we use to iter_custom() so we batch all our iterations for one Criterion sample, instead of measuring microbenchmark iterations one by one.

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.

@copilot address this 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.

Addressed in 85f62a3.

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.

@copilot there are still a lot of iterations(1) remaining in the diff! Those are all anti-patterns to fix, you only addressed a few of them. Also merge latest origin/main and resolve conflicts.

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.

Addressed in 4a66ba7.

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.

[Copilot speaking]

F004 — [P2] Batch the remaining multitude allocation measurements per Criterion sample

Status: Follow-up

Impacted locations:

Ten allocation-tracked benchmarks still use Bencher::iter and create a measure_thread().iterations(1) span inside every individual benchmark iteration. Span creation, counter capture, aggregation, and drop are therefore paid and timed once per workload operation instead of once per Criterion sample.

alloc_tracker 0.7 documents that measurement overhead is on the order of tens of nanoseconds and states that batching multiple iterations in one sample is crucial to amortize it. The rest of this migration follows that iter_custom pattern, but the decode, reuse, and refresh-workload cases in this file remain on the one-span-per-iteration pattern.

Reproducible reasoning:

  1. Bencher::iter invokes the closure once per timed iteration.
  2. Each listed closure opens and drops a tracker span around one workload call.
  3. .iterations(1) satisfies the new API requirement but does not amortize measurement overhead.
  4. The upstream canonical pattern opens one span in iter_custom, sets .iterations(iters), and runs the operation iters times.

Consequence: These timings include a fixed tracker cost for every operation and are not methodologically comparable with the correctly batched benchmarks elsewhere in the PR. The overhead can conceal or exaggerate workload deltas, especially for the shorter reuse and refresh operations.

Recommended action: Convert all ten cases to iter_custom, open one tracker span with .iterations(iters) for the sample, and execute the workload iters times inside the timed loop. Preserve the current mutable-state semantics by keeping each state object outside the repeated closure.

References:

Existing thread: Follow-up to discussion_r3603199008, which requested removal of all remaining .iterations(1) benchmark patterns and was marked addressed.

Copilot AI review requested due to automatic review settings July 13, 2026 13:36
@dependabot
dependabot Bot removed the request for review from Copilot July 13, 2026 13:36
Copilot AI requested a review from sandersaares July 13, 2026 13:39
Copilot AI requested a review from psandana July 29, 2026 16:02
Comment thread crates/benchmarking/src/lib.rs Outdated
/// Times a Criterion sample after preparing per-iteration inputs ahead of time.
pub fn time_sample_with_inputs<T, R>(mut setup: impl FnMut() -> T, mut bench: impl FnMut(T) -> R) -> impl FnMut(u64) -> Duration {
move |iters| {
let inputs = (0..iters).map(|_| setup()).collect::<Vec<_>>();

@sandersaares sandersaares Jul 30, 2026

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.

@copilot this is not right, we are constructing the inputs list ouitside the timed section; but what if we are already inside an alloc_tracker or all_the_time scope? In this case we would be also measuring the input creation, which is incorrect.

A correct approach takes a pre-prepared inputs vec here already, so the inputs can be prepared before entering any measurement scope.

Furthermore, I observe that not every benchmark that could use these helpers does so - some benchmarks still do manual timing. That seems unnecessary - unless there is some special case logic, let's use these helpers everywhere for unform and unified timing logic.

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.

Addressed in 866e38d.

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.

[Copilot speaking]

F001 — [P1] Preserve prepared input and output lifetimes outside measured samples

Status: Follow-up

Impacted locations:

time_sample_with_inputs takes the prepared Vec<T> by value, starts the timer, and then consumes the vector with for input in inputs. Each closure argument and each returned value is therefore dropped inside the timed loop, and the vector's owning iterator releases its backing allocation before start.elapsed() is evaluated. All 61 changed call sites create their alloc_tracker span before calling the helper, so the same teardown also occurs while the measurement span is active.

This does not preserve the boundary of the replaced benchmark implementations. The previous buf.rs and view.rs cases used Criterion's iter_batched_ref, and the previous bytesbuf_vs_bytes.rs loops iterated over caller-owned vectors by mutable reference. In both forms, prepared fixtures remained alive until after the routine was timed. Criterion's batched implementation also retains outputs until measurement ends.

Reproducible reasoning:

  1. Follow any prepared vector, such as the cloned multi-span views in bytesbuf_vs_bytes.rs, into time_sample_with_inputs.
  2. Instant::now() runs before the consuming for loop.
  3. The closure owns each input. Unless the input is transferred into the result, its remaining state is dropped when the closure invocation ends.
  4. _ = black_box(bench(input)); drops nontrivial results, such as BytesView or MemoryGuard, before the next iteration.
  5. The Vec::IntoIter and backing allocation are dropped before start.elapsed().
  6. The caller's tracker span is dropped only after the helper returns.

Consequence: Benchmarks for elementary reads, writes, peeks, span consumption, construction, and cold pool operations include reference-count release, span or pool cleanup, output destruction, and setup-container teardown. These costs vary by input type and span count and can dominate the operation named by the benchmark, making results non-comparable with the previous benchmarks.

Recommended action: Combine the lifetime fix with bounded batching. For each bounded chunk, prepare inputs before opening the tracker span, retain inputs and nontrivial outputs while timing the chunk, capture elapsed time, close the tracker span, and only then drop the fixtures. Use borrowed inputs for benchmarks that previously used iter_batched_ref; where consuming ownership is intrinsic to the API, move inputs into the operation but retain outputs until measurement closes. Accumulate the chunk durations to satisfy Criterion's requested iteration count.

References:

Existing thread: Follow-up to discussion_r3680525615. Moving input construction before the measurement scopes addressed setup, but input/output teardown remains inside them.

Comment thread crates/bytesbuf/benches/buf.rs Outdated
BytesBuf::new()
b.iter_custom(|iters| {
let _span = new_allocs.measure_thread().iterations(iters);
time_sample(BytesBuf::new)(iters)

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.

@copilot what's the point of time_sample returning a closure if we always immediately execute the closure? It seems overcomplicated design, no? Find opportunities to simplify - maybe we should be executing the closure-arguments already inside the time function?

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.

Simplified in a393ecc - time_sample now takes iters directly instead of returning a closure, and the benchmark call sites were updated to use the simpler API.

Copilot AI review requested due to automatic review settings July 30, 2026 06:43
@dependabot
dependabot Bot removed the request for review from Copilot July 30, 2026 06:43
Copilot AI requested a review from sandersaares July 30, 2026 06:45
Copilot AI review requested due to automatic review settings July 30, 2026 06:48
@dependabot
dependabot Bot removed the request for review from Copilot July 30, 2026 06:48
Copilot AI review requested due to automatic review settings July 30, 2026 12:59

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

Copilot reviewed 30 out of 31 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

crates/bytesbuf/benches/global_pool.rs:89

  • This benchmark buffers iters freshly-created GlobalPool values into a Vec before timing. If iters is large, that can cause very high peak memory and/or OOM before the sample even starts. Chunking the setup keeps memory bounded while still excluding setup time from the measurement.
        b.iter_custom(|iters| {
            let inputs = (0..iters).map(|_| GlobalPool::new()).collect::<Vec<_>>();
            let _span = allocs_op.measure_thread().iterations(iters);

crates/bytesbuf/benches/global_pool.rs:111

  • Collecting iters cold GlobalPool instances into a Vec can blow up memory usage when Criterion selects large iteration counts. A chunked setup keeps peak memory bounded while still keeping the setup out of the timed region.
        b.iter_custom(|iters| {
            let inputs = (0..iters).map(|_| GlobalPool::new()).collect::<Vec<_>>();
            let _span = allocs_op.measure_thread().iterations(iters);

crates/bytesbuf/benches/global_pool.rs:77

  • inputs is collected into a Vec sized to iters. Criterion can choose very large iters for fast benchmarks, so this can allocate a huge vector (and potentially OOM) before each sample. Consider chunking the setup so peak memory is bounded while still keeping setup out of the timed region.

This issue also appears in the following locations of the same file:

  • line 87
  • line 109
        b.iter_custom(|iters| {
            let inputs = (0..iters).map(|_| GlobalPool::new()).collect::<Vec<_>>();
            let _span = allocs_op.measure_thread().iterations(iters);

Comment thread crates/bytesbuf/benches/global_pool.rs Outdated

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

[Copilot speaking]

Submitted 3 findings: 1 P1 and 2 P2. All 3 are follow-ups to existing review feedback; 2 continue existing line threads and 1 is a new line comment following suppressed review feedback.

@sandersaares

Copy link
Copy Markdown
Member

@copilot address all new feedback and ensure that the branch actually builds & tests (there are failed GitHub checks - figure out what happened and fix everything that caused them to fail)

Copilot AI review requested due to automatic review settings July 30, 2026 19:20
@dependabot
dependabot Bot removed the request for review from Copilot July 30, 2026 19:20

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@copilot address all new feedback and ensure that the branch actually builds & tests (there are failed GitHub checks - figure out what happened and fix everything that caused them to fail)

Addressed in ab4791f. I fixed the remaining alloc-tracker batching issues in multitude_record_batch, introduced bounded batched timing for the affected bytesbuf benchmarks, refreshed Cargo.lock so --locked checks no longer fail, and re-ran targeted check/test coverage for the touched crates.

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

Labels

dependencies Pull requests that update a dependency file rust Pull requests that update rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants