diff options
| author | Lukas Markeffsky <@> | 2023-11-23 23:31:19 +0100 |
|---|---|---|
| committer | Lukas Markeffsky <@> | 2024-02-16 13:10:52 +0100 |
| commit | b6702939f72c6c55a74fc5f343d34c01e3d8521b (patch) | |
| tree | fdf2fca266bc817c156956d2e9e0027d8eb7e99e | |
| parent | 1e3849aed010c3ff2a4c7b7b644ca67d087ab4c1 (diff) | |
| download | rust-b6702939f72c6c55a74fc5f343d34c01e3d8521b.tar.gz rust-b6702939f72c6c55a74fc5f343d34c01e3d8521b.zip | |
outline large copies
| -rw-r--r-- | library/alloc/src/collections/vec_deque/drain.rs | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/library/alloc/src/collections/vec_deque/drain.rs b/library/alloc/src/collections/vec_deque/drain.rs index 7a413ddf971..bf8c9b2d47a 100644 --- a/library/alloc/src/collections/vec_deque/drain.rs +++ b/library/alloc/src/collections/vec_deque/drain.rs @@ -121,7 +121,27 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> { let head_len = source_deque.len(); let tail_len = new_len - head_len; + // When draining at the front (`.drain(..n)`) or at the back (`.drain(n..)`), + // we don't need to copy any data. + // Outlining this function helps LLVM to eliminate the copies in these cases. if head_len != 0 && tail_len != 0 { + copy_data(source_deque, drain_len, head_len, tail_len); + } + + if new_len == 0 { + source_deque.head = 0; + } else if head_len < tail_len { + source_deque.head = source_deque.to_physical_idx(drain_len); + } + source_deque.len = new_len; + + #[cold] + fn copy_data<T, A: Allocator>( + source_deque: &mut VecDeque<T, A>, + drain_len: usize, + head_len: usize, + tail_len: usize, + ) { let (src, dst, len); if head_len < tail_len { src = source_deque.head; @@ -137,13 +157,6 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> { source_deque.wrap_copy(src, dst, len); } } - - if new_len == 0 { - source_deque.head = 0; - } else if head_len < tail_len { - source_deque.head = source_deque.to_physical_idx(drain_len); - } - source_deque.len = new_len; } } |
