1818use std:: sync:: Arc ;
1919
2020use arrow:: array:: {
21- Array , ArrayRef , Int8Array , Int16Array , Int64Array , UInt8Array , UInt16Array ,
21+ ArrayRef , Int8Array , Int16Array , Int32Array , Int64Array , UInt8Array , UInt16Array ,
22+ UInt32Array ,
2223} ;
2324use arrow:: datatypes:: { DataType , Field , Schema } ;
2425use criterion:: { Criterion , criterion_group, criterion_main} ;
@@ -87,6 +88,20 @@ fn create_i16_array(n_distinct: usize) -> Int16Array {
8788 . collect ( )
8889}
8990
91+ fn create_u32_array ( n_distinct : usize ) -> UInt32Array {
92+ let mut rng = StdRng :: seed_from_u64 ( 42 ) ;
93+ ( 0 ..BATCH_SIZE )
94+ . map ( |_| Some ( rng. random_range ( 0 ..n_distinct as u32 ) ) )
95+ . collect ( )
96+ }
97+
98+ fn create_i32_array ( n_distinct : usize ) -> Int32Array {
99+ let mut rng = StdRng :: seed_from_u64 ( 42 ) ;
100+ ( 0 ..BATCH_SIZE )
101+ . map ( |_| Some ( rng. random_range ( 0 ..n_distinct as i32 ) ) )
102+ . collect ( )
103+ }
104+
90105fn prepare_args ( data_type : DataType ) -> ( Arc < Schema > , AccumulatorArgs < ' static > ) {
91106 let schema = Arc :: new ( Schema :: new ( vec ! [ Field :: new( "f" , data_type, true ) ] ) ) ;
92107 let schema_leaked: & ' static Schema = Box :: leak ( Box :: new ( ( * schema) . clone ( ) ) ) ;
@@ -172,6 +187,36 @@ fn count_distinct_benchmark(c: &mut Criterion) {
172187 . unwrap ( )
173188 } )
174189 } ) ;
190+
191+ // 32-bit integer types
192+
193+ // UInt32
194+ for pct in [ 80 , 99 ] {
195+ let n_distinct = BATCH_SIZE * pct / 100 ;
196+ let values = Arc :: new ( create_u32_array ( n_distinct) ) as ArrayRef ;
197+ c. bench_function ( & format ! ( "count_distinct u32 {pct}% distinct" ) , |b| {
198+ b. iter ( || {
199+ let mut accumulator = prepare_accumulator ( DataType :: UInt32 ) ;
200+ accumulator
201+ . update_batch ( std:: slice:: from_ref ( & values) )
202+ . unwrap ( )
203+ } )
204+ } ) ;
205+ }
206+
207+ // Int32
208+ for pct in [ 80 , 99 ] {
209+ let n_distinct = BATCH_SIZE * pct / 100 ;
210+ let values = Arc :: new ( create_i32_array ( n_distinct) ) as ArrayRef ;
211+ c. bench_function ( & format ! ( "count_distinct i32 {pct}% distinct" ) , |b| {
212+ b. iter ( || {
213+ let mut accumulator = prepare_accumulator ( DataType :: Int32 ) ;
214+ accumulator
215+ . update_batch ( std:: slice:: from_ref ( & values) )
216+ . unwrap ( )
217+ } )
218+ } ) ;
219+ }
175220}
176221
177222/// Create group indices with uniform distribution
@@ -197,75 +242,66 @@ fn create_skewed_groups(num_groups: usize) -> Vec<usize> {
197242 . collect ( )
198243}
199244
245+ fn create_array_for_type ( data_type : & DataType , n_distinct : usize ) -> ArrayRef {
246+ match data_type {
247+ DataType :: Int64 => Arc :: new ( create_i64_array ( n_distinct) ) as ArrayRef ,
248+ DataType :: Int32 => Arc :: new ( create_i32_array ( n_distinct) ) as ArrayRef ,
249+ DataType :: UInt32 => Arc :: new ( create_u32_array ( n_distinct) ) as ArrayRef ,
250+ DataType :: Int16 => Arc :: new ( create_i16_array ( n_distinct) ) as ArrayRef ,
251+ DataType :: UInt16 => Arc :: new ( create_u16_array ( n_distinct) ) as ArrayRef ,
252+ DataType :: Int8 => Arc :: new ( create_i8_array ( n_distinct) ) as ArrayRef ,
253+ DataType :: UInt8 => Arc :: new ( create_u8_array ( n_distinct) ) as ArrayRef ,
254+ _ => panic ! ( "Unsupported type for benchmark" ) ,
255+ }
256+ }
257+
200258fn count_distinct_groups_benchmark ( c : & mut Criterion ) {
201259 let count_fn = Count :: new ( ) ;
202260
203261 let group_counts = [ 100 , 1000 , 10000 ] ;
204262 let cardinalities = [ ( "low" , 20 ) , ( "mid" , 80 ) , ( "high" , 99 ) ] ;
205263 let distributions = [ "uniform" , "skewed" ] ;
264+ let data_types = [
265+ ( "i64" , DataType :: Int64 ) ,
266+ ( "u32" , DataType :: UInt32 ) ,
267+ ( "i32" , DataType :: Int32 ) ,
268+ ( "u16" , DataType :: UInt16 ) ,
269+ ( "i16" , DataType :: Int16 ) ,
270+ ( "u8" , DataType :: UInt8 ) ,
271+ ( "i8" , DataType :: Int8 ) ,
272+ ] ;
273+
274+ for ( type_name, data_type) in data_types {
275+ for num_groups in group_counts {
276+ for ( card_name, distinct_pct) in cardinalities {
277+ for dist in distributions {
278+ let name = format ! ( "{type_name}_g{num_groups}_{card_name}_{dist}" ) ;
279+ let n_distinct = BATCH_SIZE * distinct_pct / 100 ;
280+ let values = create_array_for_type ( & data_type, n_distinct) ;
281+ let group_indices = if dist == "uniform" {
282+ create_uniform_groups ( num_groups)
283+ } else {
284+ create_skewed_groups ( num_groups)
285+ } ;
286+
287+ let ( _schema, args) = prepare_args ( data_type. clone ( ) ) ;
206288
207- for num_groups in group_counts {
208- for ( card_name, distinct_pct) in cardinalities {
209- for dist in distributions {
210- let name = format ! ( "g{num_groups}_{card_name}_{dist}" ) ;
211- let n_distinct = BATCH_SIZE * distinct_pct / 100 ;
212- let values = Arc :: new ( create_i64_array ( n_distinct) ) as ArrayRef ;
213- let group_indices = if dist == "uniform" {
214- create_uniform_groups ( num_groups)
215- } else {
216- create_skewed_groups ( num_groups)
217- } ;
218-
219- let ( _schema, args) = prepare_args ( DataType :: Int64 ) ;
220-
221- if count_fn. groups_accumulator_supported ( args. clone ( ) ) {
222- c. bench_function ( & format ! ( "count_distinct_groups {name}" ) , |b| {
223- b. iter ( || {
224- let mut acc =
225- count_fn. create_groups_accumulator ( args. clone ( ) ) . unwrap ( ) ;
226- acc. update_batch (
227- std:: slice:: from_ref ( & values) ,
228- & group_indices,
229- None ,
230- num_groups,
231- )
232- . unwrap ( ) ;
233- acc. evaluate ( EmitTo :: All ) . unwrap ( )
234- } )
235- } ) ;
236- } else {
237- let arr = values. as_any ( ) . downcast_ref :: < Int64Array > ( ) . unwrap ( ) ;
238- let mut group_rows: Vec < Vec < i64 > > = vec ! [ Vec :: new( ) ; num_groups] ;
239- for ( idx, & group_idx) in group_indices. iter ( ) . enumerate ( ) {
240- if arr. is_valid ( idx) {
241- group_rows[ group_idx] . push ( arr. value ( idx) ) ;
242- }
289+ if count_fn. groups_accumulator_supported ( args. clone ( ) ) {
290+ c. bench_function ( & format ! ( "count_distinct_groups {name}" ) , |b| {
291+ b. iter ( || {
292+ let mut acc =
293+ count_fn. create_groups_accumulator ( args. clone ( ) ) . unwrap ( ) ;
294+ acc. update_batch (
295+ std:: slice:: from_ref ( & values) ,
296+ & group_indices,
297+ None ,
298+ num_groups,
299+ )
300+ . unwrap ( ) ;
301+ acc. evaluate ( EmitTo :: All ) . unwrap ( )
302+ } )
303+ } ) ;
243304 }
244- let group_arrays: Vec < ArrayRef > = group_rows
245- . iter ( )
246- . map ( |rows| Arc :: new ( Int64Array :: from ( rows. clone ( ) ) ) as ArrayRef )
247- . collect ( ) ;
248-
249- c. bench_function ( & format ! ( "count_distinct_groups {name}" ) , |b| {
250- b. iter ( || {
251- let mut accumulators: Vec < _ > = ( 0 ..num_groups)
252- . map ( |_| prepare_accumulator ( DataType :: Int64 ) )
253- . collect ( ) ;
254-
255- for ( group_idx, batch) in group_arrays. iter ( ) . enumerate ( ) {
256- if !batch. is_empty ( ) {
257- accumulators[ group_idx]
258- . update_batch ( std:: slice:: from_ref ( batch) )
259- . unwrap ( ) ;
260- }
261- }
262-
263- let _results: Vec < _ > = accumulators
264- . iter_mut ( )
265- . map ( |acc| acc. evaluate ( ) . unwrap ( ) )
266- . collect ( ) ;
267- } )
268- } ) ;
269305 }
270306 }
271307 }
0 commit comments