hotloop_benchmark_std/
hotloop_benchmark_std.rs

1//! ---------------------------------------------------------
2//! Runs sum benchmark comparisons on `Minarrow` and `Arrow-Rs`,
3//! at various layers of library abstraction:
4//!
5//!     1. Raw Vec / Vec64
6//!     2. Typed "inner" arrays
7//!     3. Top-level unified `Array` type
8//!
9//! Run with:
10//!     cargo run --example hotloop_benchmark_std --release
11//!
12//! Use ./benchmark_avg.sh for a realistic sample, that
13//! avoids compiler optimisations that otherwise distort
14//! the results, or the `hotloop_benchmark_avg` example.
15//! ---------------------------------------------------------
16
17#[cfg(feature = "cast_arrow")]
18use crate::benchmarks_std::run_benchmark;
19#[cfg(feature = "cast_arrow")]
20mod benchmarks_std {
21    use std::hint::black_box;
22    use std::sync::Arc;
23    use std::time::Instant;
24
25    use arrow::array::{
26        Array as ArrowArrayTrait, ArrayRef, Float64Array as ArrowF64Array,
27        Int64Array as ArrowI64Array,
28    };
29    use minarrow::{Array, Buffer, FloatArray, IntegerArray, NumericArray, Vec64};
30
31    const N: usize = 1_000;
32
33    pub(crate) fn run_benchmark() {
34        // ----------- Raw Vec<i64> -----------
35        let raw_vec: Vec<i64> = (0..N as i64).collect();
36        let start = Instant::now();
37        let mut acc = 0i64;
38        for &v in &raw_vec {
39            acc += v;
40        }
41        let dur_vec_i64 = start.elapsed();
42        println!("raw vec: Vec<i64> sum = {}, {:?}", acc, dur_vec_i64);
43        black_box(acc);
44        std::mem::drop(raw_vec);
45
46        // ----------- Raw Vec64<i64> -----------
47        let raw_vec: Vec64<i64> = (0..N as i64).collect();
48        let start = Instant::now();
49        let mut acc = 0i64;
50        for &v in &raw_vec {
51            acc += v;
52        }
53        let dur_vec_i64 = start.elapsed();
54        println!("raw vec: Vec64<i64> sum = {}, {:?}", acc, dur_vec_i64);
55        black_box(acc);
56        std::mem::drop(raw_vec);
57
58        // ----------- Minarrow i64 (direct struct, no enum) -----------
59        let min_data: Vec64<i64> = (0..N as i64).collect();
60        let start = Instant::now();
61        let int_arr = IntegerArray {
62            data: Buffer::from(min_data),
63            null_mask: None,
64        };
65        let mut acc = 0i64;
66        let slice = int_arr.data.as_slice();
67        for &v in slice {
68            acc += v;
69        }
70        let dur_minarrow_direct_i64 = start.elapsed();
71        println!(
72            "minarrow direct: IntegerArray sum = {}, {:?}",
73            acc, dur_minarrow_direct_i64
74        );
75        black_box(acc);
76        std::mem::drop(int_arr);
77
78        // ----------- Arrow i64 (struct direct) -----------
79        let data: Vec<i64> = (0..N as i64).collect();
80        let start = Instant::now();
81        let arr = ArrowI64Array::from(data);
82        let mut acc = 0i64;
83        for i in 0..arr.len() {
84            acc += arr.value(i);
85        }
86        let dur_arrow_struct_i64 = start.elapsed();
87        println!(
88            "arrow-rs struct: Int64Array sum = {}, {:?}",
89            acc, dur_arrow_struct_i64
90        );
91        black_box(acc);
92        std::mem::drop(arr);
93
94        // ----------- Minarrow i64 (enum) -----------
95        let min_data: Vec64<i64> = (0..N as i64).collect();
96        let start = Instant::now();
97        let array = Array::NumericArray(NumericArray::Int64(Arc::new(IntegerArray {
98            data: Buffer::from(min_data),
99            null_mask: None,
100        })));
101        let mut acc = 0i64;
102        let int_arr = array.num().i64().unwrap();
103        let slice = int_arr.data.as_slice();
104        for &v in slice {
105            acc += v;
106        }
107        let dur_minarrow_enum_i64 = start.elapsed();
108        println!(
109            "minarrow enum: IntegerArray sum = {}, {:?}",
110            acc, dur_minarrow_enum_i64
111        );
112        black_box(acc);
113        std::mem::drop(int_arr);
114
115        // ----------- Arrow i64 (dynamic) -----------
116        let data_dyn: Vec<i64> = (0..N as i64).collect();
117        let start = Instant::now();
118        let arr_dyn: ArrayRef = Arc::new(ArrowI64Array::from(data_dyn));
119        let mut acc = 0i64;
120        if let Some(int) = arr_dyn.as_any().downcast_ref::<ArrowI64Array>() {
121            for i in 0..int.len() {
122                acc += int.value(i);
123            }
124        }
125        let dur_arrow_dyn_i64 = start.elapsed();
126        println!(
127            "arrow-rs dyn: ArrayRef Int64Array sum = {}, {:?}",
128            acc, dur_arrow_dyn_i64
129        );
130        black_box(acc);
131        std::mem::drop(arr_dyn);
132
133        // ----------- Raw Vec<f64> -----------
134        let raw_vec: Vec<f64> = (0..N as i64).map(|x| x as f64).collect();
135        let start = Instant::now();
136        let mut acc = 0.0f64;
137        for &v in &raw_vec {
138            acc += v;
139        }
140        let dur_vec_f64 = start.elapsed();
141        println!("raw vec: Vec<f64> sum = {}, {:?}", acc, dur_vec_f64);
142        black_box(acc);
143        std::mem::drop(raw_vec);
144
145        // ----------- Raw Vec64<f64> -----------
146        let raw_vec: Vec64<f64> = (0..N as i64).map(|x| x as f64).collect();
147        let start = Instant::now();
148        let mut acc = 0.0f64;
149        for &v in &raw_vec {
150            acc += v;
151        }
152        let dur_vec_f64 = start.elapsed();
153        println!("raw vec: Vec<f64> sum = {}, {:?}", acc, dur_vec_f64);
154        black_box(acc);
155        std::mem::drop(raw_vec);
156
157        // ----------- Minarrow f64 (direct struct, no enum) -----------
158        let min_data_f64: Vec64<f64> = (0..N as i64).map(|x| x as f64).collect();
159        let start = Instant::now();
160        let float_arr = FloatArray {
161            data: Buffer::from(min_data_f64),
162            null_mask: None,
163        };
164        let mut acc = 0.0f64;
165        let slice = float_arr.data.as_slice();
166        for &v in slice {
167            acc += v;
168        }
169        let dur_minarrow_direct_f64 = start.elapsed();
170        println!(
171            "minarrow direct: FloatArray sum = {}, {:?}",
172            acc, dur_minarrow_direct_f64
173        );
174        black_box(acc);
175        std::mem::drop(float_arr);
176
177        // ----------- Arrow f64 (struct direct) -----------
178        let data_f64: Vec<f64> = (0..N as i64).map(|x| x as f64).collect();
179        let start = Instant::now();
180        let arr = ArrowF64Array::from(data_f64);
181        let mut acc = 0.0f64;
182        for i in 0..arr.len() {
183            acc += arr.value(i);
184        }
185        let dur_arrow_struct_f64 = start.elapsed();
186        println!(
187            "arrow-rs struct: Float64Array sum = {}, {:?}",
188            acc, dur_arrow_struct_f64
189        );
190        black_box(acc);
191        std::mem::drop(arr);
192
193        // ----------- Minarrow f64 (enum) -----------
194        let min_data_f64: Vec64<f64> = (0..N as i64).map(|x| x as f64).collect();
195        let start = Instant::now();
196        let array = Array::NumericArray(NumericArray::Float64(Arc::new(FloatArray {
197            data: Buffer::from(min_data_f64),
198            null_mask: None,
199        })));
200        let mut acc = 0.0f64;
201        let float_arr = array.num().f64().unwrap();
202        let slice = float_arr.data.as_slice();
203        for &v in slice {
204            acc += v;
205        }
206        let dur_minarrow_enum_f64 = start.elapsed();
207        println!(
208            "minarrow enum: FloatArray sum = {}, {:?}",
209            acc, dur_minarrow_enum_f64
210        );
211        black_box(acc);
212        std::mem::drop(float_arr);
213
214        // ----------- Arrow f64 (dynamic) -----------
215        let data_f64: Vec<f64> = (0..N as i64).map(|x| x as f64).collect();
216        let start = Instant::now();
217        let arr: ArrayRef = Arc::new(ArrowF64Array::from(data_f64));
218        let mut acc = 0.0f64;
219        if let Some(f) = arr.as_any().downcast_ref::<ArrowF64Array>() {
220            for i in 0..f.len() {
221                acc += f.value(i);
222            }
223        }
224        let dur_arrow_dyn_f64 = start.elapsed();
225        println!(
226            "arrow-rs dyn: Float64Array sum = {}, {:?}",
227            acc, dur_arrow_dyn_f64
228        );
229        black_box(acc);
230        std::mem::drop(arr);
231    }
232}
233
234fn main() {
235    if cfg!(feature = "cast_arrow") {
236        #[cfg(feature = "cast_arrow")]
237        run_benchmark()
238    } else {
239        println!("The apache-FFI example requires enabling the `cast_arrow` feature.")
240    }
241}