-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Branch on needs_drop in Vec::drop? #24280
Comments
First I've seen of needs_drop, but it seems to me that this is something best handled by general optimizations. especially for a case as simple as |
I admit I haven’t bothered writing a benchmark to find out :] |
@steveklabnik, does "needstest" include comparative benchmarks as well? |
Or is it possible to test directly the output of the optimizer to see that some bit of code that ends up doing nothing is actually optimized away? |
I don't know off the top of my head, to be honest. |
(i don't think this qualifies as "needstest"; that is usually applied to issues, usually bugs, where the only remaining task post bug fix was to put in a regression test. The use of the word "test" in the title for this issue is referring to a conditional in the low-level code, not a regression test; not sure if that was part of confusion here or not. Anyway, removing the E-needstest label.) |
(i would not object, however, if we used a hypothetical |
Ah, yes, "test" in the title was meant as "use an |
@SimonSapin ohhhhhhhhhhh yeah, I just had a parsing error 😉 |
Because it caught my attention, I spent most of the morning tinkering on this. I even built the exact revision of LLVM that Rust master is using so I could use the I believe I've come to the conclusion that the drop-loop is optimized out for This is the code I used to test this: fn main() {
(0..256).collect::<Vec<_>>();
} I then compiled it with Now, I can't really read LLVM IR, but I only see one But I could be wrong. This is half-gibberish to me. |
Branching will make things easier in the unoptimized case for things like |
@sfackler I hadn't considered the unoptimized case. 👍 to branching from me. |
@cybergeek94 Is |
@kballard Correct me if I'm wrong, but doesn't |
@cybergeek94 Ok: "you're wrong" 😉 If you pass the |
Well, I learned how to build LLVM and work with IR, so maybe not a total waste. |
I have some image processing code that has to display video. It meets timings with -O2, but that takes 20s to compile. With -O0, it takes 4s, which gives a more reasonable feedback loop, but then it calls drop_in_place for every u8 in a 12MB Vec. I have a workaround, which is really terrible: unsafe {
let mut data = <whatever we drop>;
let raw_vec = alloc::raw_vec::RawVec::from_raw_parts(
data.as_mut_ptr(), data.capacity());
mem::forget(data);
mem::drop(raw_vec);
} |
By the way, |
@bluss Thanks! |
So even if a loop of no-op drops is optimized away, it sounds like skipping it entirely based on @gankro does it sound reasonable to do across all collections? |
@SimonSapin it's a bit of a bumber to have to do, but it seems reasonable, yeah. |
With -O2, LLVM's inliner can remove this code, but this does not happen with -O1 and lower. As a result, dropping Vec<u8> was linear with length, resulting in abysmal performance for large buffers. See issue #24280.
Fixed by #28531? There’s still no |
Yeah, I’d say this is fixed. I don’t think |
|
When a
arena::TypedArena
is dropped, it usesstd::intrinsics::needs_drop
to skip entirely the loop that reads items and runs their destructors.Vec
however does no such thing, and runs a similar loop unconditionally. Should it checkneeds_drop
as well, or can we rely on the loop being optimized away entirely when it does nothing?cc @pnkfelix, @gankro
The text was updated successfully, but these errors were encountered: