Auto merge of #128234 - jcsp:retain-empty-case, r=tgross35 · patricklam/verify-rust-std@f70ce7f (original) (raw)
Navigation Menu
- GitHub Copilot Write better code with AI
- GitHub Models New Manage and compare prompts
- GitHub Advanced Security Find and fix vulnerabilities
- Actions Automate any workflow
- Codespaces Instant dev environments
- Issues Plan and track work
- Code Review Manage code changes
- Discussions Collaborate outside of code
- Code Search Find more, search less
- Explore
- Pricing
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Appearance settings
Commit f70ce7f
Auto merge of rust-lang#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: 
File tree
1 file changed
lines changed
1 file changed
lines changed
Lines changed: 6 additions & 0 deletions
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1710,6 +1710,12 @@ impl<T, A: Allocator> Vec<T, A> { | ||
1710 | 1710 | F: FnMut(&mut T) -> bool, |
1711 | 1711 | { |
1712 | 1712 | let original_len = self.len(); |
1713 | + | |
1714 | +if original_len == 0 { | |
1715 | +// Empty case: explicit return allows better optimization, vs letting compiler infer it | |
1716 | +return; | |
1717 | +} | |
1718 | + | |
1713 | 1719 | // Avoid double drop if the drop guard is not executed, |
1714 | 1720 | // since we may make some holes during the process. |
1715 | 1721 | unsafe { self.set_len(0) }; |