mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #128234 - jcsp:retain-empty-case, r=tgross35
Optimize empty case in Vec::retain While profiling some code that happens to call Vec::retain() in a tight loop, I noticed more runtime than expected in retain, even in a bench case where the vector was always empty. When I wrapped my call to retain in `if !myvec.is_empty()` I saw faster execution compared with doing retain on an empty vector. On closer inspection, Vec::retain is doing set_len(0) on itself even when the vector is empty, and then resetting the length again in BackshiftOnDrop::drop. Unscientific screengrab of a flamegraph illustrating how we end up spending time in set_len and drop: ![image](https://github.com/user-attachments/assets/ebc72ace-84a0-4432-9b6f-1b3c96d353ba)
This commit is contained in:
commit
dba8e2d2c2
@ -1710,6 +1710,12 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
F: FnMut(&mut T) -> bool,
|
F: FnMut(&mut T) -> bool,
|
||||||
{
|
{
|
||||||
let original_len = self.len();
|
let original_len = self.len();
|
||||||
|
|
||||||
|
if original_len == 0 {
|
||||||
|
// Empty case: explicit return allows better optimization, vs letting compiler infer it
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid double drop if the drop guard is not executed,
|
// Avoid double drop if the drop guard is not executed,
|
||||||
// since we may make some holes during the process.
|
// since we may make some holes during the process.
|
||||||
unsafe { self.set_len(0) };
|
unsafe { self.set_len(0) };
|
||||||
|
Loading…
Reference in New Issue
Block a user