#![allow(missing_docs, reason = "Benchmark")]
#![allow(unused_results, reason = "black_box of bench input is intentional")]
#![allow(clippy::unwrap_used, reason = "benchmark code")]
#![allow(
clippy::needless_pass_by_value,
reason = "gungraun bench inputs are passed by value by the framework"
)]
#![allow(clippy::type_complexity, reason = "benchmark state tuples are inherently complex")]
#![allow(clippy::too_many_lines, reason = "benchmark file")]
use core::hint::black_box;
use std::rc::Rc as StdRc;
use gungraun::{Callgrind, LibraryBenchmarkConfig, library_benchmark, library_benchmark_group, main};
use multitude::{Arena, Rc as ArenaRc};
const PROPERTIES: usize = 8;
const PROPERTY_SIZE: usize = 16;
const N: usize = 1_000;
type GlobalArray = StdRc<[StdRc<[u8]>]>;
type ArenaArrayOfArena = ArenaRc<[ArenaRc<[u8]>]>;
type ArenaArrayOfGlobal = ArenaRc<[StdRc<[u8]>]>;
fn build_global(payload: &[u8]) -> GlobalArray {
let mut properties = Vec::with_capacity(PROPERTIES);
for _ in 0..PROPERTIES {
properties.push(StdRc::<[u8]>::from(payload));
}
StdRc::from(properties)
}
fn build_global_from_slice(properties: &[StdRc<[u8]>]) -> GlobalArray {
StdRc::from(properties)
}
fn build_arena(arena: &Arena, payload: &[u8]) -> ArenaArrayOfArena {
let mut properties = arena.alloc_vec_with_capacity::<ArenaRc<[u8]>>(PROPERTIES);
for _ in 0..PROPERTIES {
properties.push(arena.alloc_slice_copy_rc(payload));
}
properties.try_into_rc_slice().unwrap()
}
fn build_arena_from_slice(arena: &Arena, properties: &[StdRc<[u8]>]) -> ArenaArrayOfGlobal {
arena.alloc_slice_clone_rc(properties)
}
fn payload() -> Vec<u8> {
vec![0xAB_u8; PROPERTY_SIZE]
}
fn global_properties() -> Vec<StdRc<[u8]>> {
let payload = payload();
(0..PROPERTIES).map(|_| StdRc::<[u8]>::from(payload.as_slice())).collect()
}
fn warm_arena() -> Arena {
let arena = Arena::builder().with_capacity(128 * 1024).build();
let _ = arena.alloc(0_u64);
let _ = arena.alloc_rc(0_u64);
arena
}
fn setup_global() -> (Vec<u8>, Vec<GlobalArray>) {
(payload(), Vec::with_capacity(N))
}
fn setup_arena() -> (Arena, Vec<u8>, Vec<ArenaArrayOfArena>) {
(warm_arena(), payload(), Vec::with_capacity(N))
}
fn setup_global_from_slice() -> (Vec<StdRc<[u8]>>, Vec<GlobalArray>) {
(global_properties(), Vec::with_capacity(N))
}
fn setup_arena_from_slice() -> (Arena, Vec<StdRc<[u8]>>, Vec<ArenaArrayOfGlobal>) {
(warm_arena(), global_properties(), Vec::with_capacity(N))
}
#[library_benchmark]
#[bench::run(setup_global())]
fn global(state: (Vec<u8>, Vec<GlobalArray>)) -> (Vec<u8>, Vec<GlobalArray>) {
let (payload, mut out) = state;
for _ in 0..N {
out.push(black_box(build_global(black_box(&payload))));
}
(payload, out)
}
#[library_benchmark]
#[bench::run(setup_arena())]
fn arena(state: (Arena, Vec<u8>, Vec<ArenaArrayOfArena>)) -> (Arena, Vec<u8>, Vec<ArenaArrayOfArena>) {
let (arena, payload, mut out) = state;
for _ in 0..N {
out.push(black_box(build_arena(&arena, black_box(&payload))));
}
(arena, payload, out)
}
#[library_benchmark]
#[bench::run(setup_global_from_slice())]
fn global_from_slice(state: (Vec<StdRc<[u8]>>, Vec<GlobalArray>)) -> (Vec<StdRc<[u8]>>, Vec<GlobalArray>) {
let (properties, mut out) = state;
for _ in 0..N {
out.push(black_box(build_global_from_slice(black_box(&properties))));
}
(properties, out)
}
#[library_benchmark]
#[bench::run(setup_arena_from_slice())]
fn arena_from_slice(state: (Arena, Vec<StdRc<[u8]>>, Vec<ArenaArrayOfGlobal>)) -> (Arena, Vec<StdRc<[u8]>>, Vec<ArenaArrayOfGlobal>) {
let (arena, properties, mut out) = state;
for _ in 0..N {
out.push(black_box(build_arena_from_slice(&arena, black_box(&properties))));
}
(arena, properties, out)
}
library_benchmark_group!(
name = rc_array_group;
benchmarks = global, arena, global_from_slice, arena_from_slice
);
main!(
config = LibraryBenchmarkConfig::default()
.tool(Callgrind::with_args(["--branch-sim=yes"]));
library_benchmark_groups = rc_array_group
);