drain_inverse improve performance

master
Avril 4 years ago
parent 6b3b117a6f
commit f996d34bdf
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -25,25 +25,62 @@ pub trait FindSliceBounds
pub trait SliceInPlace
{
fn slice_in_place(&mut self, slice: Range<usize>);
#[deprecated = "Slow. Use `drain_inverse`"]
#[inline]
fn slice_in_place<R: std::ops::RangeBounds<usize>>(&mut self, slice: R)
{
self.drain_inverse(slice);
}
fn drain_inverse<R: std::ops::RangeBounds<usize>>(&mut self, slice: R);
}
impl SliceInPlace for String
{
fn slice_in_place(&mut self, slice: Range<usize>) {
fn slice_in_place<R: std::ops::RangeBounds<usize>>(&mut self, slice: R) {
let mut i=0;
self.retain(|_| (slice.contains(&i), i+=1).0);
}
fn drain_inverse<R: std::ops::RangeBounds<usize>>(&mut self, slice: R)
{
use std::ops::Bound;
match slice.end_bound() {
Bound::Excluded(&ex) => drop(self.drain(ex..)),
Bound::Included(&inc) => drop(self.drain(inc+1..)),
_ => (),
};
match slice.start_bound() {
Bound::Included(&ex) => drop(self.drain(..ex)),
Bound::Excluded(&ex) => drop(..ex+1),
_ => ()
};
}
}
impl<T> SliceInPlace for Vec<T>
{
fn slice_in_place(&mut self, slice: Range<usize>) {
fn slice_in_place<R: std::ops::RangeBounds<usize>>(&mut self, slice: R) {
let mut i=0;
self.retain(|_| (slice.contains(&i), i+=1).0);
}
fn drain_inverse<R: std::ops::RangeBounds<usize>>(&mut self, slice: R)
{
use std::ops::Bound;
match slice.end_bound() {
Bound::Excluded(&ex) => drop(self.drain(ex..)),
Bound::Included(&inc) => drop(self.drain(inc+1..)),
_ => (),
};
match slice.start_bound() {
Bound::Included(&ex) => drop(self.drain(..ex)),
Bound::Excluded(&ex) => drop(..ex+1),
_ => ()
};
}
}
impl<T: ?Sized + AsRef<str>> FindSliceBounds for T
{
type SliceType = str;
@ -72,6 +109,8 @@ impl<T: ?Sized + AsRef<str>> FindSliceBounds for T
#[cfg(test)]
mod test_slice_in_place
{
use test::{Bencher, black_box};
use super::*;
#[test]
fn slice_in_place_str()
@ -85,6 +124,36 @@ mod test_slice_in_place
assert_eq!(&string[string.slice_bounds(string.trim())], string.trim());
assert_eq!(&string[string.slice_bounds(string.trim())], "hello world");
}
#[bench]
fn bench_slice_in_place(b: &mut Bencher)
{
let mut string = String::from("hello ONE TWO world");
b.iter(|| {
black_box(string.slice_in_place(7..16));
string.push_str("ONE TWO");
});
}
#[bench]
fn bench_drain_inverse(b: &mut Bencher)
{
let mut string = String::from("hello ONE TWO world");
b.iter(|| {
black_box(string.drain_inverse(7..16));
string.push_str("ONE TWO");
});
}
#[test]
fn drain_inverse()
{
let mut string = String::from("123hello world5678");
string.drain_inverse(3..=13);
assert_eq!(&string[..], "hello world");
string.drain_inverse(6..);
assert_eq!(&string[..], "world");
}
}

@ -274,7 +274,7 @@ impl KeyHeader
}
buffer.slice_bounds(trimmed)
};
buffer.slice_in_place(bounds);
buffer.drain_inverse(bounds);
if {
let bytes = buffer.as_bytes();

Loading…
Cancel
Save