@@ -105,54 +105,38 @@ macro_rules! spezialize_for_lengths {
105
105
( $separator: expr, $target: expr, $iter: expr; $( $num: expr) ,* ) => {
106
106
let mut target = $target;
107
107
let iter = $iter;
108
- let sep_len = $separator. len( ) ;
109
108
let sep_bytes = $separator;
110
109
match $separator. len( ) {
111
110
$(
112
111
// loops with hardcoded sizes run much faster
113
112
// specialize the cases with small separator lengths
114
113
$num => {
115
114
for s in iter {
116
- target. get_unchecked_mut( ..$num)
117
- . copy_from_slice( sep_bytes) ;
118
-
119
- let s_bytes = s. borrow( ) . as_ref( ) ;
120
- let offset = s_bytes. len( ) ;
121
- target = { target} . get_unchecked_mut( $num..) ;
122
- target. get_unchecked_mut( ..offset)
123
- . copy_from_slice( s_bytes) ;
124
- target = { target} . get_unchecked_mut( offset..) ;
115
+ copy_slice_and_advance!( target, sep_bytes) ;
116
+ copy_slice_and_advance!( target, s. borrow( ) . as_ref( ) ) ;
125
117
}
126
118
} ,
127
119
) *
128
- 0 => {
129
- // concat, same principle without the separator
130
- for s in iter {
131
- let s_bytes = s. borrow( ) . as_ref( ) ;
132
- let offset = s_bytes. len( ) ;
133
- target. get_unchecked_mut( ..offset)
134
- . copy_from_slice( s_bytes) ;
135
- target = { target} . get_unchecked_mut( offset..) ;
136
- }
137
- } ,
138
120
_ => {
139
121
// arbitrary non-zero size fallback
140
122
for s in iter {
141
- target. get_unchecked_mut( ..sep_len)
142
- . copy_from_slice( sep_bytes) ;
143
-
144
- let s_bytes = s. borrow( ) . as_ref( ) ;
145
- let offset = s_bytes. len( ) ;
146
- target = { target} . get_unchecked_mut( sep_len..) ;
147
- target. get_unchecked_mut( ..offset)
148
- . copy_from_slice( s_bytes) ;
149
- target = { target} . get_unchecked_mut( offset..) ;
123
+ copy_slice_and_advance!( target, sep_bytes) ;
124
+ copy_slice_and_advance!( target, s. borrow( ) . as_ref( ) ) ;
150
125
}
151
126
}
152
127
}
153
128
} ;
154
129
}
155
130
131
+ macro_rules! copy_slice_and_advance {
132
+ ( $target: expr, $bytes: expr) => {
133
+ let len = $bytes. len( ) ;
134
+ $target. get_unchecked_mut( ..len)
135
+ . copy_from_slice( $bytes) ;
136
+ $target = { $target} . get_unchecked_mut( len..) ;
137
+ }
138
+ }
139
+
156
140
// Optimized join implementation that works for both Vec<T> (T: Copy) and String's inner vec
157
141
// Currently (2018-05-13) there is a bug with type inference and specialization (see issue #36262)
158
142
// For this reason SliceConcatExt<T> is not specialized for T: Copy and SliceConcatExt<str> is the
@@ -193,7 +177,7 @@ where
193
177
// copy separator and strs over without bounds checks
194
178
// generate loops with hardcoded offsets for small separators
195
179
// massive improvements possible (~ x2)
196
- spezialize_for_lengths ! ( sep, target, iter; 1 , 2 , 3 , 4 ) ;
180
+ spezialize_for_lengths ! ( sep, target, iter; 0 , 1 , 2 , 3 , 4 ) ;
197
181
}
198
182
result. set_len ( len) ;
199
183
}
0 commit comments