@@ -104,54 +104,38 @@ macro_rules! spezialize_for_lengths {
104104 ( $separator: expr, $target: expr, $iter: expr; $( $num: expr) ,* ) => {
105105 let mut target = $target;
106106 let iter = $iter;
107- let sep_len = $separator. len( ) ;
108107 let sep_bytes = $separator;
109108 match $separator. len( ) {
110109 $(
111110 // loops with hardcoded sizes run much faster
112111 // specialize the cases with small separator lengths
113112 $num => {
114113 for s in iter {
115- target. get_unchecked_mut( ..$num)
116- . copy_from_slice( sep_bytes) ;
117-
118- let s_bytes = s. borrow( ) . as_ref( ) ;
119- let offset = s_bytes. len( ) ;
120- target = { target} . get_unchecked_mut( $num..) ;
121- target. get_unchecked_mut( ..offset)
122- . copy_from_slice( s_bytes) ;
123- target = { target} . get_unchecked_mut( offset..) ;
114+ copy_slice_and_advance!( target, sep_bytes) ;
115+ copy_slice_and_advance!( target, s. borrow( ) . as_ref( ) ) ;
124116 }
125117 } ,
126118 ) *
127- 0 => {
128- // concat, same principle without the separator
129- for s in iter {
130- let s_bytes = s. borrow( ) . as_ref( ) ;
131- let offset = s_bytes. len( ) ;
132- target. get_unchecked_mut( ..offset)
133- . copy_from_slice( s_bytes) ;
134- target = { target} . get_unchecked_mut( offset..) ;
135- }
136- } ,
137119 _ => {
138120 // arbitrary non-zero size fallback
139121 for s in iter {
140- target. get_unchecked_mut( ..sep_len)
141- . copy_from_slice( sep_bytes) ;
142-
143- let s_bytes = s. borrow( ) . as_ref( ) ;
144- let offset = s_bytes. len( ) ;
145- target = { target} . get_unchecked_mut( sep_len..) ;
146- target. get_unchecked_mut( ..offset)
147- . copy_from_slice( s_bytes) ;
148- target = { target} . get_unchecked_mut( offset..) ;
122+ copy_slice_and_advance!( target, sep_bytes) ;
123+ copy_slice_and_advance!( target, s. borrow( ) . as_ref( ) ) ;
149124 }
150125 }
151126 }
152127 } ;
153128}
154129
130+ macro_rules! copy_slice_and_advance {
131+ ( $target: expr, $bytes: expr) => {
132+ let len = $bytes. len( ) ;
133+ $target. get_unchecked_mut( ..len)
134+ . copy_from_slice( $bytes) ;
135+ $target = { $target} . get_unchecked_mut( len..) ;
136+ }
137+ }
138+
155139// Optimized join implementation that works for both Vec<T> (T: Copy) and String's inner vec
156140// Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262)
157141// For this reason SliceConcatExt<T> is not specialized for T: Copy and SliceConcatExt<str> is the
@@ -192,7 +176,7 @@ where
192176 // copy separator and strs over without bounds checks
193177 // generate loops with hardcoded offsets for small separators
194178 // massive improvements possible (~ x2)
195- spezialize_for_lengths ! ( sep, target, iter; 1 , 2 , 3 , 4 ) ;
179+ spezialize_for_lengths ! ( sep, target, iter; 0 , 1 , 2 , 3 , 4 ) ;
196180 }
197181 result. set_len ( len) ;
198182 }
0 commit comments