33
44//! In-place filter benchmarks for `BufferMut`.
55
6- use std:: fmt;
7-
86use divan:: Bencher ;
97use vortex_buffer:: BufferMut ;
108use vortex_compute:: filter:: Filter ;
@@ -16,28 +14,10 @@ fn main() {
1614
1715const BUFFER_SIZE : usize = 1024 ;
1816
19- // Full selectivity spectrum with extra detail around the 80% threshold.
2017const SELECTIVITIES : & [ f64 ] = & [
21- 0.01 , 0.05 , 0. 10, 0.15 , 0. 20, 0.25 , 0.30 , 0.50 , 0.75 , 0.78 , 0.79 , 0. 80, 0.81 , 0.82 , 0.85 , 0.99 ,
18+ 0.01 , 0.10 , 0.20 , 0.30 , 0.40 , 0.50 , 0.60 , 0.70 , 0.80 , 0.90 , 0.99 ,
2219] ;
2320
24- #[ derive( Copy , Clone , Debug ) ]
25- enum Pattern {
26- Random ,
27- Contiguous ,
28- Alternating ,
29- }
30-
31- impl fmt:: Display for Pattern {
32- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
33- match self {
34- Pattern :: Random => write ! ( f, "random" ) ,
35- Pattern :: Contiguous => write ! ( f, "contiguous" ) ,
36- Pattern :: Alternating => write ! ( f, "alternating" ) ,
37- }
38- }
39- }
40-
4121fn create_test_buffer < T > ( size : usize ) -> BufferMut < T >
4222where
4323 T : Copy + Default + From < u8 > ,
@@ -50,112 +30,25 @@ where
5030 buffer
5131}
5232
53- fn generate_mask ( len : usize , selectivity : f64 , pattern : Pattern ) -> Mask {
33+ fn generate_mask ( len : usize , selectivity : f64 ) -> Mask {
5434 #[ expect( clippy:: cast_possible_truncation) ]
5535 #[ expect( clippy:: cast_sign_loss) ]
5636 let num_selected = ( ( len as f64 ) * selectivity) . round ( ) as usize ;
5737
58- let selection = match pattern {
59- Pattern :: Random => {
60- let mut selection = vec ! [ false ; len] ;
61- let mut indices: Vec < usize > = ( 0 ..len) . collect ( ) ;
62-
63- // Simple deterministic shuffle.
64- for i in ( 1 ..len) . rev ( ) {
65- let j = ( i * 7 + 13 ) % ( i + 1 ) ;
66- indices. swap ( i, j) ;
67- }
68-
69- for i in 0 ..num_selected. min ( len) {
70- selection[ indices[ i] ] = true ;
71- }
72- selection
73- }
74- Pattern :: Contiguous => {
75- let mut selection = vec ! [ false ; len] ;
76- let start = ( len. saturating_sub ( num_selected) ) / 2 ;
77- for i in start..( start + num_selected) . min ( len) {
78- selection[ i] = true ;
79- }
80- selection
81- }
82- Pattern :: Alternating => {
83- let mut selection = vec ! [ false ; len] ;
84- if num_selected > 0 {
85- let step = len. max ( 1 ) / num_selected. max ( 1 ) ;
86- let step = step. max ( 1 ) ;
87- for i in ( 0 ..len) . step_by ( step) . take ( num_selected) {
88- selection[ i] = true ;
89- }
90- }
91- selection
92- }
93- } ;
38+ let mut selection = vec ! [ false ; len] ;
39+ let mut indices: Vec < usize > = ( 0 ..len) . collect ( ) ;
9440
95- Mask :: from_iter ( selection)
96- }
97-
98- #[ divan:: bench( types = [ u8 , u32 , u64 ] , args = SELECTIVITIES , sample_count = 1000 ) ]
99- fn filter_selectivity < T : Copy + Default + From < u8 > > ( bencher : Bencher , selectivity : f64 ) {
100- let mask = generate_mask ( BUFFER_SIZE , selectivity, Pattern :: Random ) ;
101- bencher
102- . with_inputs ( || {
103- let buffer = create_test_buffer :: < T > ( BUFFER_SIZE ) ;
104- ( buffer, mask. clone ( ) )
105- } )
106- . bench_values ( |( mut buffer, mask) | {
107- buffer. filter ( & mask) ;
108- divan:: black_box ( buffer) ;
109- } ) ;
110- }
111-
112- #[ divan:: bench_group( sample_count = 1000 ) ]
113- mod patterns_at_threshold {
114- use super :: * ;
115-
116- const SELECTIVITY : f64 = 0.50 ;
117-
118- #[ divan:: bench]
119- fn random ( bencher : Bencher ) {
120- let mask = generate_mask ( BUFFER_SIZE , SELECTIVITY , Pattern :: Random ) ;
121- bencher
122- . with_inputs ( || {
123- let buffer = create_test_buffer :: < u32 > ( BUFFER_SIZE ) ;
124- ( buffer, mask. clone ( ) )
125- } )
126- . bench_values ( |( mut buffer, mask) | {
127- buffer. filter ( & mask) ;
128- divan:: black_box ( buffer) ;
129- } ) ;
41+ // Simple deterministic shuffle.
42+ for i in ( 1 ..len) . rev ( ) {
43+ let j = ( i * 7 + 13 ) % ( i + 1 ) ;
44+ indices. swap ( i, j) ;
13045 }
13146
132- #[ divan:: bench]
133- fn contiguous ( bencher : Bencher ) {
134- let mask = generate_mask ( BUFFER_SIZE , SELECTIVITY , Pattern :: Contiguous ) ;
135- bencher
136- . with_inputs ( || {
137- let buffer = create_test_buffer :: < u32 > ( BUFFER_SIZE ) ;
138- ( buffer, mask. clone ( ) )
139- } )
140- . bench_values ( |( mut buffer, mask) | {
141- buffer. filter ( & mask) ;
142- divan:: black_box ( buffer) ;
143- } ) ;
47+ for i in 0 ..num_selected. min ( len) {
48+ selection[ indices[ i] ] = true ;
14449 }
14550
146- #[ divan:: bench]
147- fn alternating ( bencher : Bencher ) {
148- let mask = generate_mask ( BUFFER_SIZE , SELECTIVITY , Pattern :: Alternating ) ;
149- bencher
150- . with_inputs ( || {
151- let buffer = create_test_buffer :: < u32 > ( BUFFER_SIZE ) ;
152- ( buffer, mask. clone ( ) )
153- } )
154- . bench_values ( |( mut buffer, mask) | {
155- buffer. filter ( & mask) ;
156- divan:: black_box ( buffer) ;
157- } ) ;
158- }
51+ Mask :: from_iter ( selection)
15952}
16053
16154#[ derive( Copy , Clone , Default ) ]
@@ -168,12 +61,12 @@ impl From<u8> for LargeElement {
16861 }
16962}
17063
171- #[ divan:: bench( args = SELECTIVITIES , sample_count = 1000 ) ]
172- fn filter_large_element ( bencher : Bencher , selectivity : f64 ) {
173- let mask = generate_mask ( BUFFER_SIZE , selectivity, Pattern :: Random ) ;
64+ #[ divan:: bench( types = [ u8 , u32 , u64 , LargeElement ] , args = SELECTIVITIES , sample_count = 1000 ) ]
65+ fn filter_selectivity < T : Copy + Default + From < u8 > > ( bencher : Bencher , selectivity : f64 ) {
66+ let mask = generate_mask ( BUFFER_SIZE , selectivity) ;
17467 bencher
17568 . with_inputs ( || {
176- let buffer = create_test_buffer :: < LargeElement > ( BUFFER_SIZE ) ;
69+ let buffer = create_test_buffer :: < T > ( BUFFER_SIZE ) ;
17770 ( buffer, mask. clone ( ) )
17871 } )
17972 . bench_values ( |( mut buffer, mask) | {
0 commit comments