modular-bitfield-msb 0.11.2

Allows to easily define bitfield types with modular building blocks. MSB-first version.
Documentation
//! In this benchmark we compare the macro generated code for
//! setters and getters to some hand-written code for the same
//! data structure.
//!
//! We do a performance analysis for the getter and setter of
//! all fields of both structs.
//!
//! Also we test here that our hand-written code and the macro
//! generated code actually are semantically equivalent.
//! This allows us to further enhance the hand-written code
//! and to eventually come up with new optimization tricks
//! for the macro generated code while staying correct.

mod handwritten;
mod utils;

use criterion::{
    black_box,
    criterion_group,
    criterion_main,
    Criterion,
};
use handwritten::{
    Generated,
    Handwritten,
};
use utils::repeat;

criterion_group!(
    bench_get,
    bench_get_a,
    bench_get_b,
    bench_get_c,
    bench_get_d,
    bench_get_e,
    bench_get_f,
);
criterion_group!(
    bench_set,
    bench_set_a,
    bench_set_b,
    bench_set_c,
    bench_set_d,
    bench_set_e,
    bench_set_f,
);
criterion_main!(bench_get, bench_set);

macro_rules! generate_cmp_benchmark_for {
    (
        test($test_name_get:ident, $test_name_set:ident) {
            fn $fn_get:ident($name_get:literal);
            fn $fn_set:ident($name_set:literal);
        }
    ) => {
        fn $test_name_get(c: &mut Criterion) {
            let mut g = c.benchmark_group($name_get);
            g.bench_function("generated", |b| {
                let input = black_box(Generated::new());
                b.iter(|| {
                    repeat(|| {
                        black_box(input.$fn_get());
                    })
                });
            });
            g.bench_function("handwritten", |b| {
                let input = Handwritten::new();
                b.iter(|| {
                    repeat(|| {
                        black_box(input.$fn_get());
                    })
                });
            });
        }

        fn $test_name_set(c: &mut Criterion) {
            let mut g = c.benchmark_group($name_set);
            g.bench_function("generated", |b| {
                let mut input = Generated::new();
                b.iter(|| {
                    repeat(|| {
                        black_box(black_box(&mut input).$fn_set(1));
                    })
                });
            });
            g.bench_function("handwritten", |b| {
                let mut input = Handwritten::new();
                b.iter(|| {
                    repeat(|| {
                        black_box(black_box(&mut input).$fn_set(1));
                    })
                });
            });
        }
    };
}
generate_cmp_benchmark_for!(
    test(bench_get_a, bench_set_a) {
        fn a("generated_vs_handwritten/get_a");
        fn set_a("generated_vs_handwritten/set_a");
    }
);
generate_cmp_benchmark_for!(
    test(bench_get_b, bench_set_b) {
        fn b("generated_vs_handwritten/get_b");
        fn set_b("generated_vs_handwritten/set_b");
    }
);
generate_cmp_benchmark_for!(
    test(bench_get_c, bench_set_c) {
        fn c("generated_vs_handwritten/get_c");
        fn set_c("generated_vs_handwritten/set_c");
    }
);
generate_cmp_benchmark_for!(
    test(bench_get_d, bench_set_d) {
        fn d("generated_vs_handwritten/get_d");
        fn set_d("generated_vs_handwritten/set_d");
    }
);
generate_cmp_benchmark_for!(
    test(bench_get_e, bench_set_e) {
        fn e("generated_vs_handwritten/get_e");
        fn set_e("generated_vs_handwritten/set_e");
    }
);
generate_cmp_benchmark_for!(
    test(bench_get_f, bench_set_f) {
        fn f("generated_vs_handwritten/get_f");
        fn set_f("generated_vs_handwritten/set_f");
    }
);