@@ -14,7 +14,6 @@ use crate::Array;
1414use crate :: IntoArray ;
1515use crate :: ToCanonical ;
1616use crate :: arrays:: ListViewArray ;
17- use crate :: builders:: builder_with_capacity;
1817use crate :: compute;
1918use crate :: vtable:: ValidityHelper ;
2019
@@ -103,18 +102,14 @@ impl ListViewArray {
103102 } )
104103 }
105104
106- // TODO(connor)[ListView]: We should benchmark if it is faster to use `take` on the elements
107- // instead of using a builder.
108105 /// The inner function for `rebuild_zero_copy_to_list`, which rebuilds a `ListViewArray` piece
109106 /// by piece.
107+ ///
108+ /// Collects all element indices into a flat `BufferMut<u64>` and performs a single bulk
109+ /// `take` to produce the new elements array.
110110 fn naive_rebuild < O : IntegerPType , NewOffset : IntegerPType , S : IntegerPType > (
111111 & self ,
112112 ) -> VortexResult < ListViewArray > {
113- let element_dtype = self
114- . dtype ( )
115- . as_list_element_opt ( )
116- . vortex_expect ( "somehow had a canonical list that was not a list" ) ;
117-
118113 let offsets_canonical = self . offsets ( ) . to_primitive ( ) ;
119114 let offsets_slice = offsets_canonical. as_slice :: < O > ( ) ;
120115 let sizes_canonical = self . sizes ( ) . to_primitive ( ) ;
@@ -129,17 +124,8 @@ impl ListViewArray {
129124 // null lists to 0.
130125 let mut new_sizes = BufferMut :: < S > :: with_capacity ( len) ;
131126
132- // Canonicalize the elements up front as we will be slicing the elements quite a lot.
133- let elements_canonical = self
134- . elements ( )
135- . to_canonical ( )
136- . vortex_expect ( "canonicalize elements for rebuild" )
137- . into_array ( ) ;
138-
139- // Note that we do not know what the exact capacity should be of the new elements since
140- // there could be overlaps in the existing `ListViewArray`.
141- let mut new_elements_builder =
142- builder_with_capacity ( element_dtype. as_ref ( ) , self . elements ( ) . len ( ) ) ;
127+ // Collect all element indices for a single bulk take.
128+ let mut take_indices = BufferMut :: < u64 > :: with_capacity ( self . elements ( ) . len ( ) ) ;
143129
144130 let mut n_elements = NewOffset :: zero ( ) ;
145131 for index in 0 ..len {
@@ -159,14 +145,14 @@ impl ListViewArray {
159145
160146 new_offsets. push ( n_elements) ;
161147 new_sizes. push ( size) ;
162- new_elements_builder . extend_from_array ( & elements_canonical . slice ( start..stop) ? ) ;
148+ take_indices . extend ( start as u64 ..stop as u64 ) ;
163149
164150 n_elements += num_traits:: cast ( size) . vortex_expect ( "Cast failed" ) ;
165151 }
166152
167153 let offsets = new_offsets. into_array ( ) ;
168154 let sizes = new_sizes. into_array ( ) ;
169- let elements = new_elements_builder . finish ( ) ;
155+ let elements = self . elements ( ) . take ( take_indices . into_array ( ) ) ? ;
170156
171157 debug_assert_eq ! (
172158 n_elements. as_( ) ,
0 commit comments