# reciprocal 0.1.2

Baseline implementation of integer division by constants
Documentation
``````use criterion::black_box;
use criterion::criterion_group;
use criterion::Criterion;

const ITER: usize = 10000;
const OFFSET: u64 = 0x9f1668016f482246;
const MULTIPLIER: u64 = 0xf6ee9cc7a7f7d033;

const DIVISORS: [u64; 4] = [2, 3, 7, 11];

fn generate(i: usize) -> u64 {
}

fn generate_div_indices(n: usize) -> Vec<usize> {
use rand::distributions::Distribution;
use rand::SeedableRng;

let range = rand::distributions::Uniform::<usize>::new(0, DIVISORS.len());
let mut rand: rand_chacha::ChaChaRng = SeedableRng::seed_from_u64(1);

(0..n).map(|_| range.sample(&mut rand)).collect()
}

fn hardware_u64_div(c: &mut Criterion) {
let inputs: Vec<u64> = (0..ITER).map(generate).collect();
let divisors: Vec<u64> = generate_div_indices(ITER)
.iter()
.map(|i| DIVISORS[*i])
.collect();

c.bench_function("hardware_u64_div", move |b| {
b.iter(|| {
let mut sum = 0;
for (i, div) in black_box(&inputs).iter().zip(black_box(&divisors)) {
sum += i / div;
}

black_box(sum)
})
});
}

fn partial_u64_div(c: &mut Criterion) {
use reciprocal::PartialReciprocal;

let inputs: Vec<u64> = (0..ITER).map(generate).collect();
let reciprocals: Vec<_> = DIVISORS
.iter()
.map(|i| PartialReciprocal::new(*i).unwrap())
.collect();
let divisors: Vec<&PartialReciprocal> = generate_div_indices(ITER)
.iter()
.map(|i| &reciprocals[*i])
.collect();

c.bench_function("partial_u64_div", move |b| {
b.iter(|| {
let mut sum = 0;
for (i, div) in black_box(&inputs).iter().zip(black_box(&divisors)) {
sum += div.apply(*i);
}

black_box(sum)
})
});
}

fn reciprocal_u64_div(c: &mut Criterion) {
use reciprocal::Reciprocal;

let inputs: Vec<u64> = (0..ITER).map(generate).collect();
let reciprocals: Vec<_> = DIVISORS
.iter()
.map(|i| Reciprocal::new(*i).unwrap())
.collect();
let divisors: Vec<&Reciprocal> = generate_div_indices(ITER)
.iter()
.map(|i| &reciprocals[*i])
.collect();

c.bench_function("reciprocal_u64_div", move |b| {
b.iter(|| {
let mut sum = 0;
for (i, div) in black_box(&inputs).iter().zip(black_box(&divisors)) {
sum += div.apply(*i);
}

black_box(sum)
})
});
}

fn strength_reduce_u64_div(c: &mut Criterion) {
use strength_reduce::StrengthReducedU64;

let inputs: Vec<u64> = (0..ITER).map(generate).collect();
let reciprocals: Vec<_> = DIVISORS
.iter()
.map(|i| StrengthReducedU64::new(*i))
.collect();
let divisors: Vec<&StrengthReducedU64> = generate_div_indices(ITER)
.iter()
.map(|i| &reciprocals[*i])
.collect();

c.bench_function("strength_reduce_u64_div", move |b| {
b.iter(|| {
let mut sum = 0;
for (i, div) in black_box(&inputs).iter().zip(black_box(&divisors)) {
sum += *i / **div;
}

black_box(sum)
})
});
}

fn fast_divide_u64_div(c: &mut Criterion) {
use fastdivide::DividerU64;

let inputs: Vec<u64> = (0..ITER).map(generate).collect();
let reciprocals: Vec<_> = DIVISORS.iter().map(|i| DividerU64::divide_by(*i)).collect();
let divisors: Vec<&DividerU64> = generate_div_indices(ITER)
.iter()
.map(|i| &reciprocals[*i])
.collect();

c.bench_function("fast_divide_u64_div", move |b| {
b.iter(|| {
let mut sum = 0;
for (i, div) in black_box(&inputs).iter().zip(black_box(&divisors)) {
sum += div.divide(*i);
}

black_box(sum)
})
});
}

criterion_group!(
u64_div_variable,
hardware_u64_div,
partial_u64_div,
reciprocal_u64_div,
strength_reduce_u64_div,
fast_divide_u64_div
);

criterion::criterion_main!(u64_div_variable);
``````