@@ -104,54 +104,38 @@ macro_rules! spezialize_for_lengths {
104
104
( $separator: expr, $target: expr, $iter: expr; $( $num: expr) ,* ) => {
105
105
let mut target = $target;
106
106
let iter = $iter;
107
- let sep_len = $separator. len( ) ;
108
107
let sep_bytes = $separator;
109
108
match $separator. len( ) {
110
109
$(
111
110
// loops with hardcoded sizes run much faster
112
111
// specialize the cases with small separator lengths
113
112
$num => {
114
113
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( ) ) ;
124
116
}
125
117
} ,
126
118
) *
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
- } ,
137
119
_ => {
138
120
// arbitrary non-zero size fallback
139
121
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( ) ) ;
149
124
}
150
125
}
151
126
}
152
127
} ;
153
128
}
154
129
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
+
155
139
// Optimized join implementation that works for both Vec<T> (T: Copy) and String's inner vec
156
140
// Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262)
157
141
// For this reason SliceConcatExt<T> is not specialized for T: Copy and SliceConcatExt<str> is the
@@ -192,7 +176,7 @@ where
192
176
// copy separator and strs over without bounds checks
193
177
// generate loops with hardcoded offsets for small separators
194
178
// 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 ) ;
196
180
}
197
181
result. set_len ( len) ;
198
182
}
0 commit comments