hotloop_benchmark_avg_std/
hotloop_benchmark_avg_std.rs1#[cfg(feature = "cast_arrow")]
18use crate::benchmarks_avg::run_benchmark;
19#[cfg(feature = "cast_arrow")]
20mod benchmarks_avg {
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 use crate::fmt_duration_ns;
32
33 const N: usize = 1000;
34 const ITERATIONS: usize = 1000;
35
36 pub(crate) fn run_benchmark() {
37 let mut total_arrow_dyn_i64 = std::time::Duration::ZERO;
38 let mut total_arrow_struct_i64 = std::time::Duration::ZERO;
39 let mut total_minarrow_enum_i64 = std::time::Duration::ZERO;
40 let mut total_minarrow_direct_i64 = std::time::Duration::ZERO;
41 let mut total_vec_i64 = std::time::Duration::ZERO;
42 let mut total_arrow_dyn_f64 = std::time::Duration::ZERO;
43 let mut total_arrow_struct_f64 = std::time::Duration::ZERO;
44 let mut total_minarrow_enum_f64 = std::time::Duration::ZERO;
45 let mut total_minarrow_direct_f64 = std::time::Duration::ZERO;
46 let mut total_vec_f64 = std::time::Duration::ZERO;
47
48 for _ in 0..ITERATIONS {
49 let data: Vec<i64> = (0..N as i64).collect();
51 let start = Instant::now();
52 let arr: ArrayRef = Arc::new(ArrowI64Array::from(data));
53 let mut acc = 0i64;
54 if let Some(int) = arr.as_any().downcast_ref::<ArrowI64Array>() {
55 for i in 0..int.len() {
56 acc += int.value(i);
57 }
58 }
59 let dur_arrow_dyn_i64 = start.elapsed();
60 total_arrow_dyn_i64 += dur_arrow_dyn_i64;
61 black_box(acc);
62
63 let data: Vec<i64> = (0..N as i64).collect();
65 let start = Instant::now();
66 let arr = ArrowI64Array::from(data);
67 let mut acc = 0i64;
68 for i in 0..arr.len() {
69 acc += arr.value(i);
70 }
71 let dur_arrow_struct_i64 = start.elapsed();
72 total_arrow_struct_i64 += dur_arrow_struct_i64;
73 black_box(acc);
74
75 let min_data: Vec64<i64> = (0..N as i64).collect();
77 let start = Instant::now();
78 let array = Array::NumericArray(NumericArray::Int64(Arc::new(IntegerArray {
79 data: Buffer::from(min_data),
80 null_mask: None
81 })));
82 let mut acc = 0i64;
83 let int_arr = array.num().i64().unwrap();
84 let slice = int_arr.data.as_slice();
85 for &v in slice {
86 acc += v;
87 }
88 let dur_minarrow_enum_i64 = start.elapsed();
89 total_minarrow_enum_i64 += dur_minarrow_enum_i64;
90 black_box(acc);
91
92 let min_data: Vec64<i64> = (0..N as i64).collect();
94 let start = Instant::now();
95 let int_arr = IntegerArray {
96 data: Buffer::from(min_data),
97 null_mask: None
98 };
99 let mut acc = 0i64;
100 let slice = int_arr.data.as_slice();
101 for &v in slice {
102 acc += v;
103 }
104 let dur_minarrow_direct_i64 = start.elapsed();
105 total_minarrow_direct_i64 += dur_minarrow_direct_i64;
106 black_box(acc);
107
108 let raw_vec: Vec<i64> = (0..N as i64).collect();
110 let start = Instant::now();
111 let mut acc = 0i64;
112 for &v in &raw_vec {
113 acc += v;
114 }
115 let dur_vec_i64 = start.elapsed();
116 total_vec_i64 += dur_vec_i64;
117 black_box(acc);
118
119 let data_f64: Vec<f64> = (0..N as i64).map(|x| x as f64).collect();
121 let start = Instant::now();
122 let arr: ArrayRef = Arc::new(ArrowF64Array::from(data_f64));
123 let mut acc = 0.0f64;
124 if let Some(f) = arr.as_any().downcast_ref::<ArrowF64Array>() {
125 for i in 0..f.len() {
126 acc += f.value(i);
127 }
128 }
129 let dur_arrow_dyn_f64 = start.elapsed();
130 total_arrow_dyn_f64 += dur_arrow_dyn_f64;
131 black_box(acc);
132
133 let data_f64: Vec<f64> = (0..N as i64).map(|x| x as f64).collect();
135 let start = Instant::now();
136 let arr = ArrowF64Array::from(data_f64);
137 let mut acc = 0.0f64;
138 for i in 0..arr.len() {
139 acc += arr.value(i);
140 }
141 let dur_arrow_struct_f64 = start.elapsed();
142 total_arrow_struct_f64 += dur_arrow_struct_f64;
143 black_box(acc);
144
145 let min_data_f64: Vec64<f64> = (0..N as i64).map(|x| x as f64).collect();
147 let start = Instant::now();
148 let array = Array::NumericArray(NumericArray::Float64(Arc::new(FloatArray {
149 data: Buffer::from(min_data_f64),
150 null_mask: None
151 })));
152 let mut acc = 0.0f64;
153 let float_arr = array.num().f64().unwrap();
154 let slice = float_arr.data.as_slice();
155 for &v in slice {
156 acc += v;
157 }
158 let dur_minarrow_enum_f64 = start.elapsed();
159 total_minarrow_enum_f64 += dur_minarrow_enum_f64;
160 black_box(acc);
161
162 let min_data_f64: Vec64<f64> = (0..N as i64).map(|x| x as f64).collect();
164 let start = Instant::now();
165 let float_arr = FloatArray {
166 data: Buffer::from(min_data_f64),
167 null_mask: None
168 };
169 let mut acc = 0.0f64;
170 let slice = float_arr.data.as_slice();
171 for &v in slice {
172 acc += v;
173 }
174 let dur_minarrow_direct_f64 = start.elapsed();
175 total_minarrow_direct_f64 += dur_minarrow_direct_f64;
176 black_box(acc);
177
178 let raw_vec: Vec<f64> = (0..N as i64).map(|x| x as f64).collect();
180 let start = Instant::now();
181 let mut acc = 0.0f64;
182 for &v in &raw_vec {
183 acc += v;
184 }
185 let dur_vec_f64 = start.elapsed();
186 total_vec_f64 += dur_vec_f64;
187 black_box(acc);
188 }
189
190 println!("Averaged Results from {} runs:", ITERATIONS);
191 println!("---------------------------------");
192
193 let avg_vec_i64 = total_vec_i64.as_nanos() as f64 / ITERATIONS as f64;
194 let avg_minarrow_direct_i64 =
195 total_minarrow_direct_i64.as_nanos() as f64 / ITERATIONS as f64;
196 let avg_arrow_struct_i64 = total_arrow_struct_i64.as_nanos() as f64 / ITERATIONS as f64;
197 let avg_minarrow_enum_i64 = total_minarrow_enum_i64.as_nanos() as f64 / ITERATIONS as f64;
198 let avg_arrow_dyn_i64 = total_arrow_dyn_i64.as_nanos() as f64 / ITERATIONS as f64;
199
200 let avg_vec_f64 = total_vec_f64.as_nanos() as f64 / ITERATIONS as f64;
201 let avg_minarrow_direct_f64 =
202 total_minarrow_direct_f64.as_nanos() as f64 / ITERATIONS as f64;
203 let avg_arrow_struct_f64 = total_arrow_struct_f64.as_nanos() as f64 / ITERATIONS as f64;
204 let avg_minarrow_enum_f64 = total_minarrow_enum_f64.as_nanos() as f64 / ITERATIONS as f64;
205 let avg_arrow_dyn_f64 = total_arrow_dyn_f64.as_nanos() as f64 / ITERATIONS as f64;
206
207 println!(
208 "raw vec: Vec<i64> avg = {} (n={})",
209 fmt_duration_ns(avg_vec_i64),
210 ITERATIONS
211 );
212 println!(
213 "minarrow direct: IntegerArray avg = {} (n={})",
214 fmt_duration_ns(avg_minarrow_direct_i64),
215 ITERATIONS
216 );
217 println!(
218 "arrow-rs struct: Int64Array avg = {} (n={})",
219 fmt_duration_ns(avg_arrow_struct_i64),
220 ITERATIONS
221 );
222 println!();
223 println!(
224 "minarrow enum: IntegerArray avg = {} (n={})",
225 fmt_duration_ns(avg_minarrow_enum_i64),
226 ITERATIONS
227 );
228 println!(
229 "arrow-rs dyn: Int64Array avg = {} (n={})",
230 fmt_duration_ns(avg_arrow_dyn_i64),
231 ITERATIONS
232 );
233 println!();
234 println!(
235 "raw vec: Vec<f64> avg = {} (n={})",
236 fmt_duration_ns(avg_vec_f64),
237 ITERATIONS
238 );
239 println!(
240 "minarrow direct: FloatArray avg = {} (n={})",
241 fmt_duration_ns(avg_minarrow_direct_f64),
242 ITERATIONS
243 );
244 println!(
245 "arrow-rs struct: Float64Array avg = {} (n={})",
246 fmt_duration_ns(avg_arrow_struct_f64),
247 ITERATIONS
248 );
249 println!();
250 println!(
251 "minarrow enum: FloatArray avg = {} (n={})",
252 fmt_duration_ns(avg_minarrow_enum_f64),
253 ITERATIONS
254 );
255 println!(
256 "arrow-rs dyn: Float64Array avg = {} (n={})",
257 fmt_duration_ns(avg_arrow_dyn_f64),
258 ITERATIONS
259 );
260 }
261}
262
263#[cfg(feature = "cast_arrow")]
264fn fmt_duration_ns(avg_ns: f64) -> String {
265 if avg_ns < 1000.0 {
266 format!("{:.0} ns", avg_ns)
267 } else if avg_ns < 1_000_000.0 {
268 format!("{:.3} µs", avg_ns / 1000.0)
269 } else {
270 format!("{:.3} ms", avg_ns / 1_000_000.0)
271 }
272}
273
274fn main() {
275 if cfg!(feature = "cast_arrow") {
276 #[cfg(feature = "cast_arrow")]
277 run_benchmark()
278 } else {
279 println!(
280 "The hotloop_benchmark_avg_std example requires enabling the `cast_arrow` feature."
281 )
282 }
283}