From 7ca66fde95c14464e3660d56538100866e1491a1 Mon Sep 17 00:00:00 2001 From: Philippe-Cholet <44676486+Philippe-Cholet@users.noreply.github.com> Date: Thu, 14 Mar 2024 19:45:38 +0100 Subject: [PATCH] `Itertools::tail`: return `VecDeque` rather than `Vec` `rotate_left` is more efficient on `VecDeque` than on a slice. `VecDeque::from(vec)` is O(1) on recent rust. Thanks to scottmcm! --- src/lib.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index eace3242a..d18e33d99 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,7 +55,7 @@ extern crate core as std; extern crate alloc; #[cfg(feature = "use_alloc")] -use alloc::{string::String, vec::Vec}; +use alloc::{collections::VecDeque, string::String, vec::Vec}; pub use either::Either; @@ -72,6 +72,8 @@ use std::fmt::Write; use std::hash::Hash; use std::iter::{once, IntoIterator}; #[cfg(feature = "use_alloc")] +type VecDequeIntoIter = alloc::collections::vec_deque::IntoIter; +#[cfg(feature = "use_alloc")] type VecIntoIter = alloc::vec::IntoIter; use std::iter::FromIterator; @@ -3153,14 +3155,14 @@ pub trait Itertools: Iterator { /// `.rev().take(n).rev()` to have a similar result (lazy and non-allocating) /// without consuming the entire iterator. #[cfg(feature = "use_alloc")] - fn tail(self, n: usize) -> VecIntoIter + fn tail(self, n: usize) -> VecDequeIntoIter where Self: Sized, { match n { 0 => { self.last(); - Vec::new() + VecDeque::new() } 1 => self.last().into_iter().collect(), _ => { @@ -3177,7 +3179,8 @@ pub trait Itertools: Iterator { i + 1 } }); - // Respect the insertion order. + // Respect the insertion order, efficiently. + let mut data = VecDeque::from(data); data.rotate_left(idx); data }