diff options
| author | The 8472 <git@infinite-source.de> | 2023-01-01 05:22:54 +0100 |
|---|---|---|
| committer | The 8472 <git@infinite-source.de> | 2023-06-12 13:03:29 +0200 |
| commit | d89e4581594a5d96b9ddaa454de3b25d6cc34ee8 (patch) | |
| tree | a17d9024d422e1e21b73fd481e53c07ec2258a5f | |
| parent | cfb0f11a9f506292cd213872f759078d9302e0cc (diff) | |
| download | rust-d89e4581594a5d96b9ddaa454de3b25d6cc34ee8.tar.gz rust-d89e4581594a5d96b9ddaa454de3b25d6cc34ee8.zip | |
optimize slice::Iter::fold
| -rw-r--r-- | library/core/src/slice/iter/macros.rs | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 3462c0e020a..dd809ca459d 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -191,6 +191,29 @@ macro_rules! iterator { self.next_back() } + #[inline] + fn fold<B, F>(mut self, init: B, mut f: F) -> B + where + F: FnMut(B, Self::Item) -> B, + { + // Handling the 0-len case explicitly and then using a do-while style loop + // helps the optimizer. See issue #106288 + if is_empty!(self) { + return init; + } + let mut acc = init; + // SAFETY: The 0-len case was handled above so one loop iteration is guaranteed. + unsafe { + loop { + acc = f(acc, next_unchecked!(self)); + if is_empty!(self) { + break; + } + } + } + acc + } + // We override the default implementation, which uses `try_fold`, // because this simple implementation generates less LLVM IR and is // faster to compile. |
