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
35        // ----------- Raw Vec<i64> -----------
36        let raw_vec: Vec<i64> = (0..N as i64).collect();
37        let start = Instant::now();
38        let mut acc = 0i64;
39        for &v in &raw_vec {
40            acc += v;
41        }
42        let dur_vec_i64 = start.elapsed();
43        println!("raw vec: Vec<i64> sum = {}, {:?}", acc, dur_vec_i64);
44        black_box(acc);
45        std::mem::drop(raw_vec);
46
47        // ----------- Raw Vec64<i64> -----------
48        let raw_vec: Vec64<i64> = (0..N as i64).collect();
49        let start = Instant::now();
50        let mut acc = 0i64;
51        for &v in &raw_vec {
52            acc += v;
53        }
54        let dur_vec_i64 = start.elapsed();
55        println!("raw vec: Vec64<i64> sum = {}, {:?}", acc, dur_vec_i64);
56        black_box(acc);
57        std::mem::drop(raw_vec);
58
59        // ----------- Minarrow i64 (direct struct, no enum) -----------
60        let min_data: Vec64<i64> = (0..N as i64).collect();
61        let start = Instant::now();
62        let int_arr = IntegerArray {
63            data: Buffer::from(min_data),
64            null_mask: None
65        };
66        let mut acc = 0i64;
67        let slice = int_arr.data.as_slice();
68        for &v in slice {
69            acc += v;
70        }
71        let dur_minarrow_direct_i64 = start.elapsed();
72        println!("minarrow direct: IntegerArray sum = {}, {:?}", acc, dur_minarrow_direct_i64);
73        black_box(acc);
74        std::mem::drop(int_arr);
75
76        // ----------- Arrow i64 (struct direct) -----------
77        let data: Vec<i64> = (0..N as i64).collect();
78        let start = Instant::now();
79        let arr = ArrowI64Array::from(data);
80        let mut acc = 0i64;
81        for i in 0..arr.len() {
82            acc += arr.value(i);
83        }
84        let dur_arrow_struct_i64 = start.elapsed();
85        println!("arrow-rs struct: Int64Array sum = {}, {:?}", acc, dur_arrow_struct_i64);
86        black_box(acc);
87        std::mem::drop(arr);
88
89        // ----------- Minarrow i64 (enum) -----------
90        let min_data: Vec64<i64> = (0..N as i64).collect();
91        let start = Instant::now();
92        let array = Array::NumericArray(NumericArray::Int64(Arc::new(IntegerArray {
93            data: Buffer::from(min_data),
94            null_mask: None
95        })));
96        let mut acc = 0i64;
97        let int_arr = array.num().i64().unwrap();
98        let slice = int_arr.data.as_slice();
99        for &v in slice {
100            acc += v;
101        }
102        let dur_minarrow_enum_i64 = start.elapsed();
103        println!("minarrow enum: IntegerArray sum = {}, {:?}", acc, dur_minarrow_enum_i64);
104        black_box(acc);
105        std::mem::drop(int_arr);
106
107        // ----------- Arrow i64 (dynamic) -----------
108        let data_dyn: Vec<i64> = (0..N as i64).collect();
109        let start = Instant::now();
110        let arr_dyn: ArrayRef = Arc::new(ArrowI64Array::from(data_dyn));
111        let mut acc = 0i64;
112        if let Some(int) = arr_dyn.as_any().downcast_ref::<ArrowI64Array>() {
113            for i in 0..int.len() {
114                acc += int.value(i);
115            }
116        }
117        let dur_arrow_dyn_i64 = start.elapsed();
118        println!("arrow-rs dyn: ArrayRef Int64Array sum = {}, {:?}", acc, dur_arrow_dyn_i64);
119        black_box(acc);
120        std::mem::drop(arr_dyn);
121
122        // ----------- Raw Vec<f64> -----------
123        let raw_vec: Vec<f64> = (0..N as i64).map(|x| x as f64).collect();
124        let start = Instant::now();
125        let mut acc = 0.0f64;
126        for &v in &raw_vec {
127            acc += v;
128        }
129        let dur_vec_f64 = start.elapsed();
130        println!("raw vec: Vec<f64> sum = {}, {:?}", acc, dur_vec_f64);
131        black_box(acc);
132        std::mem::drop(raw_vec);
133
134        // ----------- Raw Vec64<f64> -----------
135        let raw_vec: Vec64<f64> = (0..N as i64).map(|x| x as f64).collect();
136        let start = Instant::now();
137        let mut acc = 0.0f64;
138        for &v in &raw_vec {
139            acc += v;
140        }
141        let dur_vec_f64 = start.elapsed();
142        println!("raw vec: Vec<f64> sum = {}, {:?}", acc, dur_vec_f64);
143        black_box(acc);
144        std::mem::drop(raw_vec);
145
146        // ----------- Minarrow f64 (direct struct, no enum) -----------
147        let min_data_f64: Vec64<f64> = (0..N as i64).map(|x| x as f64).collect();
148        let start = Instant::now();
149        let float_arr = FloatArray {
150            data: Buffer::from(min_data_f64),
151            null_mask: None
152        };
153        let mut acc = 0.0f64;
154        let slice = float_arr.data.as_slice();
155        for &v in slice {
156            acc += v;
157        }
158        let dur_minarrow_direct_f64 = start.elapsed();
159        println!("minarrow direct: FloatArray sum = {}, {:?}", acc, dur_minarrow_direct_f64);
160        black_box(acc);
161        std::mem::drop(float_arr);
162        
163        // ----------- Arrow f64 (struct direct) -----------
164        let data_f64: Vec<f64> = (0..N as i64).map(|x| x as f64).collect();
165        let start = Instant::now();
166        let arr = ArrowF64Array::from(data_f64);
167        let mut acc = 0.0f64;
168        for i in 0..arr.len() {
169            acc += arr.value(i);
170        }
171        let dur_arrow_struct_f64 = start.elapsed();
172        println!("arrow-rs struct: Float64Array sum = {}, {:?}", acc, dur_arrow_struct_f64);
173        black_box(acc);
174        std::mem::drop(arr);
175
176        // ----------- Minarrow f64 (enum) -----------
177        let min_data_f64: Vec64<f64> = (0..N as i64).map(|x| x as f64).collect();
178        let start = Instant::now();
179        let array = Array::NumericArray(NumericArray::Float64(Arc::new(FloatArray {
180            data: Buffer::from(min_data_f64),
181            null_mask: None
182        })));
183        let mut acc = 0.0f64;
184        let float_arr = array.num().f64().unwrap();
185        let slice = float_arr.data.as_slice();
186        for &v in slice {
187            acc += v;
188        }
189        let dur_minarrow_enum_f64 = start.elapsed();
190        println!("minarrow enum: FloatArray sum = {}, {:?}", acc, dur_minarrow_enum_f64);
191        black_box(acc);
192        std::mem::drop(float_arr);
193
194
195        // ----------- Arrow f64 (dynamic) -----------
196        let data_f64: Vec<f64> = (0..N as i64).map(|x| x as f64).collect();
197        let start = Instant::now();
198        let arr: ArrayRef = Arc::new(ArrowF64Array::from(data_f64));
199        let mut acc = 0.0f64;
200        if let Some(f) = arr.as_any().downcast_ref::<ArrowF64Array>() {
201            for i in 0..f.len() {
202                acc += f.value(i);
203            }
204        }
205        let dur_arrow_dyn_f64 = start.elapsed();
206        println!("arrow-rs dyn: Float64Array sum = {}, {:?}", acc, dur_arrow_dyn_f64);
207        black_box(acc);
208        std::mem::drop(arr);
209
210    }
211}
212
213fn main() {
214    if cfg!(feature = "cast_arrow") {
215        #[cfg(feature = "cast_arrow")]
216        run_benchmark()
217    } else {
218        println!("The apache-FFI example requires enabling the `cast_arrow` feature.")
219    }
220}