compacts join code

This commit is contained in:
Emerentius 2018-05-23 07:20:37 +02:00
parent b2fd7da0cf
commit d0d0885c3f

View File

@ -104,7 +104,6 @@ macro_rules! spezialize_for_lengths {
($separator:expr, $target:expr, $iter:expr; $($num:expr),*) => {
let mut target = $target;
let iter = $iter;
let sep_len = $separator.len();
let sep_bytes = $separator;
match $separator.len() {
$(
@ -112,46 +111,31 @@ macro_rules! spezialize_for_lengths {
// specialize the cases with small separator lengths
$num => {
for s in iter {
target.get_unchecked_mut(..$num)
.copy_from_slice(sep_bytes);
let s_bytes = s.borrow().as_ref();
let offset = s_bytes.len();
target = {target}.get_unchecked_mut($num..);
target.get_unchecked_mut(..offset)
.copy_from_slice(s_bytes);
target = {target}.get_unchecked_mut(offset..);
copy_slice_and_advance!(target, sep_bytes);
copy_slice_and_advance!(target, s.borrow().as_ref());
}
},
)*
0 => {
// concat, same principle without the separator
for s in iter {
let s_bytes = s.borrow().as_ref();
let offset = s_bytes.len();
target.get_unchecked_mut(..offset)
.copy_from_slice(s_bytes);
target = {target}.get_unchecked_mut(offset..);
}
},
_ => {
// arbitrary non-zero size fallback
for s in iter {
target.get_unchecked_mut(..sep_len)
.copy_from_slice(sep_bytes);
let s_bytes = s.borrow().as_ref();
let offset = s_bytes.len();
target = {target}.get_unchecked_mut(sep_len..);
target.get_unchecked_mut(..offset)
.copy_from_slice(s_bytes);
target = {target}.get_unchecked_mut(offset..);
copy_slice_and_advance!(target, sep_bytes);
copy_slice_and_advance!(target, s.borrow().as_ref());
}
}
}
};
}
macro_rules! copy_slice_and_advance {
($target:expr, $bytes:expr) => {
let len = $bytes.len();
$target.get_unchecked_mut(..len)
.copy_from_slice($bytes);
$target = {$target}.get_unchecked_mut(len..);
}
}
// Optimized join implementation that works for both Vec<T> (T: Copy) and String's inner vec
// Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262)
// For this reason SliceConcatExt<T> is not specialized for T: Copy and SliceConcatExt<str> is the
@ -192,7 +176,7 @@ where
// copy separator and strs over without bounds checks
// generate loops with hardcoded offsets for small separators
// massive improvements possible (~ x2)
spezialize_for_lengths!(sep, target, iter; 1, 2, 3, 4);
spezialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4);
}
result.set_len(len);
}