@@ -174,15 +174,26 @@ fn compress<T: Clone + Copy + PartialEq>(
174174 let mut r = Vec :: new ( ) ; // Result vector
175175 r. resize ( row_length, empty_val) ;
176176
177- let mut dv = Vec :: new ( ) ; // displacement vector
178- dv. resize ( sorted. len ( ) , 0 ) ;
177+ let mut dv = vec ! [ 0 ; sorted. len( ) ] ; // displacement vector
179178
179+ let mut tmp = Vec :: new ( ) ;
180180 for s in sorted {
181- let slice = & vec[ s * row_length..( s + 1 ) * row_length] ;
181+ // The row we're about to iterate over typically contains mostly empty values that can
182+ // never succeed with `fits`. We pre-filter out all those empty values up-front, such that
183+ // `tmp` contains `(index, non-empty-value)` pairs that we can then pass to `fits`. Because
184+ // this is such a tight loop, we reuse the same `Vec` to avoid repeated allocations.
185+ tmp. clear ( ) ;
186+ tmp. extend (
187+ vec[ s * row_length..( s + 1 ) * row_length]
188+ . iter ( )
189+ . enumerate ( )
190+ . filter ( |( _, v) | * * v != empty_val) ,
191+ ) ;
192+
182193 let mut d = 0 ; // displacement value
183194 loop {
184- if fits ( slice , & r, d, empty_val) {
185- apply ( slice , & mut r, d, empty_val ) ;
195+ if fits ( tmp . as_slice ( ) , & r, d, empty_val) {
196+ apply ( tmp . as_slice ( ) , & mut r, d) ;
186197 dv[ * s] = d;
187198 break ;
188199 } else {
@@ -196,27 +207,24 @@ fn compress<T: Clone + Copy + PartialEq>(
196207 ( r, dv)
197208}
198209
199- fn fits < T : PartialEq > ( v : & [ T ] , target : & [ T ] , d : usize , empty_val : T ) -> bool {
200- for i in 0 ..v. len ( ) {
201- if v[ i] != empty_val && target[ d + i] != empty_val && target[ d + i] != v[ i] {
210+ /// `v` is an array of `(index, non-empty_val)` pairs.
211+ fn fits < T : PartialEq > ( v : & [ ( usize , & T ) ] , target : & [ T ] , d : usize , empty_val : T ) -> bool {
212+ for ( i, x) in v {
213+ if target[ d + i] != empty_val && target[ d + i] != * * x {
202214 return false ;
203215 }
204216 }
205217 true
206218}
207219
208- fn apply < T : Copy + PartialEq > ( v : & [ T ] , target : & mut [ T ] , d : usize , empty_val : T ) {
209- for i in 0 ..v. len ( ) {
210- if v[ i] != empty_val {
211- target[ d + i] = v[ i]
212- }
220+ /// `v` is an array of `(index, non-empty_val)` pairs.
221+ fn apply < T : Copy + PartialEq > ( v : & [ ( usize , & T ) ] , target : & mut [ T ] , d : usize ) {
222+ for ( i, x) in v {
223+ target[ d + i] = * * x;
213224 }
214225}
215226
216- fn sort < T : PartialEq > ( v : & [ T ] , empty_val : T , row_length : usize ) -> Vec < usize >
217- where
218- T : PartialEq < T > ,
219- {
227+ fn sort < T : PartialEq > ( v : & [ T ] , empty_val : T , row_length : usize ) -> Vec < usize > {
220228 let mut o: Vec < usize > = ( 0 ..v. len ( ) / row_length) . collect ( ) ;
221229 o. sort_by_key ( |x| {
222230 v[ ( x * row_length) ..( ( x + 1 ) * row_length) ]
0 commit comments