-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clean up Vec's benchmarks #83458
Clean up Vec's benchmarks #83458
Conversation
Many of the Vec benchmarks assert what values should be produced by the benchmarked code. In some cases, these asserts dominate the runtime of the benchmarks they are in, causing the benchmarks to understate the impact of an optimization or regression.
r? @dtolnay (rust-highfive has picked a reviewer for you, use r? to override) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bench_in_place_zip_iter_mut
doesn't callzip
My bad, I could have picked better name. If I recall correctly it was baseline to which bench_in_place_zip_recycle
gets compared.
bench_in_place*
don't do anything in-place...
There's a specialization for vec.into_iter()....collect()
which reuses the allocation, it should be exercising that.
b.iter(|| { | ||
let v: Vec<u32> = Vec::with_capacity(src_len); | ||
assert_eq!(v.len(), 0); | ||
assert_eq!(v.capacity(), src_len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note that benchmarks are also executed when you run ./x.py test
, i.e. they can double as test-cases. If you remove those asserts here because they get in the way of measuring things you'll have to check if there are roughtly equivalent proper tests somewhere.
They seem to be quite trivial, so hopefully this isn't the only place where this stuff is tested, but I'd still check.
When I read the name of these benchmarks, I was expecting to find an implementation that doesn't allocate or free. In my mind, the whole point of an operation being in-place is that it doesn't allocate or free. So my concern/confusion is that the Do we want to demonstrate the impact of the |
It still should be half the amount of malloc/frees compared to the naive approach. Which was possible to see when I did before/after benchmarks when developing. But granted it took quite some noise-reduction on my system to even see the effects. The
Well, the iter_mut based one should already be doing the same, but sure something based on alignment might be a more obvious baseline. |
Try benchmarking with incremental compilation off and codgenunits == 1 if that's not already the case. Without that the codegen partitioning ruins some inline opportunities in easily perturbed ways. |
I believe I already have those settings? Those are the defaults, as far as I can tell. Though honestly the whole |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! I am happy you are willing to get these in better shape.
I am on board with removing asserts from the benchmarks. Trying to get the benchmark suite to serve double duty as tests and benchmarks seems misguided. Too much test-only code inline complicates seeing what is actually being benchmarked. The functionality of cargo test
/ x.py test
of also running 1 iteration of your benchmarks is just to smoke test that they don't crash, it isn't meant to be the place that you do the main exhaustive testing of library functionality.
A number of these benchmarks are poorly-named. Should I fix these, or is there tooling that depend on the names not changing?
I do not know of anything like that. Feel free to fix the names.
@bors r+ |
📌 Commit 8c88418 has been approved by |
☀️ Test successful - checks-actions |
The Vec benchmarks need a lot of love. I sort of noticed this in #83357 but the overall situation is much less awesome than I thought at the time. The first commit just removes a lot of asserts and does a touch of other cleanup.
A number of these benchmarks are poorly-named. For example,
bench_map_fast
is not in fact fast,bench_rev_1
andbench_rev_2
are vague,bench_in_place_zip_iter_mut
doesn't callzip
,bench_in_place*
don't do anything in-place... Should I fix these, or is there tooling that depend on the names not changing?I've also noticed that
bench_rev_1
andbench_rev_2
are remarkably fragile. It looks like poking other code inVec
can cause the codegen of this benchmark to switch to a version that has almost exactly half its current throughput and I have absolutely no idea why.Here's the fast version:
And the slow one: