Skip to content

Commit 67fca34

Browse files
committed
Add benchmarks for average_ceil as well
1 parent 7581fcb commit 67fca34

File tree

1 file changed

+113
-9
lines changed

1 file changed

+113
-9
lines changed

benches/average.rs

Lines changed: 113 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ extern crate num_integer;
66
extern crate num_traits;
77
extern crate test;
88

9-
use std::cmp::{min, max};
10-
use std::fmt::Debug;
119
use num_integer::Integer;
1210
use num_traits::{AsPrimitive, PrimInt, WrappingAdd, WrappingMul};
11+
use std::cmp::{max, min};
12+
use std::fmt::Debug;
1313
use test::{black_box, Bencher};
1414

1515
// --- Utilities for RNG ----------------------------------------------------
@@ -66,15 +66,15 @@ macro_rules! naive_average {
6666
}
6767
}
6868
fn naive_average_ceil(&self, other: &$T) -> $T {
69-
match self.checked_add(*other).and_then(|x| x.checked_add(1)) {
69+
match self.checked_add(*other) {
7070
Some(z) => z.div_ceil(&2),
7171
None => {
7272
if self > other {
7373
let diff = self - other;
74-
self - diff / 2
74+
self - diff.div_floor(&2)
7575
} else {
7676
let diff = other - self;
77-
other - diff / 2
77+
other - diff.div_floor(&2)
7878
}
7979
}
8080
}
@@ -102,7 +102,7 @@ macro_rules! modulo_average {
102102
fn modulo_average_ceil(&self, other: &$T) -> $T {
103103
let (q1, r1) = self.div_mod_floor(&2);
104104
let (q2, r2) = other.div_mod_floor(&2);
105-
q1 + q2 + (r1 * r2)
105+
q1 + q2 + (r1 | r2)
106106
}
107107
fn modulo_average_floor(&self, other: &$T) -> $T {
108108
let (q1, r1) = self.div_mod_floor(&2);
@@ -135,10 +135,21 @@ where
135135
for &(i, j) in v {
136136
let rt = f(&i, &j);
137137
let (a, b) = (min(i, j), max(i, j));
138-
if (b - a).is_even() {
139-
assert_eq!(rt - a, b - rt);
138+
println!("( {:?} + {:?} )/ 2 = {:?}", a, b, rt);
139+
// if both number are the same sign, check rt is in the middle
140+
if (a < T::zero()) == (b < T::zero()) {
141+
if (b - a).is_even() {
142+
assert_eq!(rt - a, b - rt);
143+
} else {
144+
assert_eq!(rt - a, b - rt + T::one());
145+
}
146+
// if both number have a different sign,
140147
} else {
141-
assert_eq!(rt - a, b - rt + T::one());
148+
if (a + b).is_even() {
149+
assert_eq!(rt, (a + b) / (T::one() + T::one()))
150+
} else {
151+
assert_eq!(rt, (a + b + T::one()) / (T::one() + T::one()))
152+
}
142153
}
143154
}
144155
bench_unchecked(b, v, f);
@@ -211,6 +222,99 @@ macro_rules! bench_average {
211222
.collect()
212223
}
213224

225+
mod ceil {
226+
227+
use super::*;
228+
229+
mod small {
230+
231+
use super::*;
232+
233+
#[bench]
234+
fn optimized(b: &mut Bencher) {
235+
let v = small();
236+
bench_ceil(b, &v, |x: &$T, y: &$T| x.average_ceil(y));
237+
}
238+
239+
#[bench]
240+
fn naive(b: &mut Bencher) {
241+
let v = small();
242+
bench_ceil(b, &v, |x: &$T, y: &$T| x.naive_average_ceil(y));
243+
}
244+
245+
#[bench]
246+
fn unchecked(b: &mut Bencher) {
247+
let v = small();
248+
bench_unchecked(b, &v, |x: &$T, y: &$T| x.unchecked_average_ceil(y));
249+
}
250+
251+
#[bench]
252+
fn modulo(b: &mut Bencher) {
253+
let v = small();
254+
bench_ceil(b, &v, |x: &$T, y: &$T| x.modulo_average_ceil(y));
255+
}
256+
}
257+
258+
mod overflowing {
259+
260+
use super::*;
261+
262+
#[bench]
263+
fn optimized(b: &mut Bencher) {
264+
let v = overflowing();
265+
bench_ceil(b, &v, |x: &$T, y: &$T| x.average_ceil(y));
266+
}
267+
268+
#[bench]
269+
fn naive(b: &mut Bencher) {
270+
let v = overflowing();
271+
bench_ceil(b, &v, |x: &$T, y: &$T| x.naive_average_ceil(y));
272+
}
273+
274+
#[bench]
275+
fn unchecked(b: &mut Bencher) {
276+
let v = overflowing();
277+
bench_unchecked(b, &v, |x: &$T, y: &$T| x.unchecked_average_ceil(y));
278+
}
279+
280+
#[bench]
281+
fn modulo(b: &mut Bencher) {
282+
let v = overflowing();
283+
bench_ceil(b, &v, |x: &$T, y: &$T| x.modulo_average_ceil(y));
284+
}
285+
}
286+
287+
mod rand {
288+
289+
use super::*;
290+
291+
#[bench]
292+
fn optimized(b: &mut Bencher) {
293+
let v = rand();
294+
bench_ceil(b, &v, |x: &$T, y: &$T| x.average_ceil(y));
295+
}
296+
297+
#[bench]
298+
fn naive(b: &mut Bencher) {
299+
let v = rand();
300+
bench_ceil(b, &v, |x: &$T, y: &$T| x.naive_average_ceil(y));
301+
}
302+
303+
#[bench]
304+
fn unchecked(b: &mut Bencher) {
305+
let v = rand();
306+
bench_unchecked(b, &v, |x: &$T, y: &$T| x.unchecked_average_ceil(y));
307+
}
308+
309+
#[bench]
310+
fn modulo(b: &mut Bencher) {
311+
let v = rand();
312+
bench_ceil(b, &v, |x: &$T, y: &$T| x.modulo_average_ceil(y));
313+
}
314+
}
315+
316+
}
317+
214318
mod floor {
215319

216320
use super::*;

0 commit comments

Comments
 (0)