Skip to content

Instantly share code, notes, and snippets.

@bruceg
Created October 26, 2021 15:32
Show Gist options
  • Select an option

  • Save bruceg/32f16b19adbe743703724a73f383a3f1 to your computer and use it in GitHub Desktop.

Select an option

Save bruceg/32f16b19adbe743703724a73f383a3f1 to your computer and use it in GitHub Desktop.
use criterion::{
black_box, criterion_group, criterion_main,
measurement::{Measurement, WallTime},
BenchmarkId, Criterion,
};
use criterion_linux_perf::{PerfMeasurement, PerfMode};
use smallvec::SmallVec;
use std::mem::{drop, size_of};
use tinyvec::TinyVec;
#[derive(Default)]
struct LogEvent([u64; 9]);
#[derive(Default)]
struct Metric([u64; 22]);
enum Event {
Log(LogEvent),
Metric(Metric),
}
enum EventsVec {
Logs(Vec<LogEvent>),
Metrics(Vec<Metric>),
}
enum EventsSmallVec {
Logs(SmallVec<[LogEvent; 1]>),
Metrics(SmallVec<[Metric; 1]>),
}
enum EventsTinyVec {
Logs(TinyVec<[LogEvent; 1]>),
Metrics(TinyVec<[Metric; 1]>),
}
impl EventsVec {
fn into_iter(self) -> impl Iterator<Item = Event> {
match self {
Self::Logs(v) => v.into_iter().map(Event::Log),
Self::Metrics(v) => unimplemented!(),
}
}
}
impl EventsSmallVec {
fn into_iter(self) -> impl Iterator<Item = Event> {
match self {
Self::Logs(v) => v.into_iter().map(Event::Log),
Self::Metrics(v) => unimplemented!(),
}
}
}
impl EventsTinyVec {
fn into_iter(self) -> impl Iterator<Item = Event> {
match self {
Self::Logs(v) => v.into_iter().map(Event::Log),
Self::Metrics(v) => unimplemented!(),
}
}
}
fn make_vec(events: usize) -> EventsVec {
let mut result = Vec::with_capacity(events);
for i in 0..events {
result.push(LogEvent([events as u64; 9]));
}
EventsVec::Logs(result)
}
fn make_smallvec(events: usize) -> EventsSmallVec {
let mut result = SmallVec::with_capacity(events);
for i in 0..events {
result.push(LogEvent([events as u64; 9]));
}
EventsSmallVec::Logs(result)
}
fn make_tinyvec(events: usize) -> EventsTinyVec {
let mut result = TinyVec::with_capacity(events);
for i in 0..events {
result.push(LogEvent([events as u64; 9]));
}
EventsTinyVec::Logs(result)
/* EventsTinyVec::Logs(
(0..events)
.into_iter()
.map(|_| LogEvent([events as u64; 9]))
.collect(),
)*/
}
fn count_vec(events: EventsVec) -> u64 {
events
.into_iter()
.map(|event| match event {
Event::Log(log) => log.0[1],
Event::Metric(metric) => metric.0[1],
})
.sum()
}
fn count_smallvec(events: EventsSmallVec) -> u64 {
events
.into_iter()
.map(|event| match event {
Event::Log(log) => log.0[1],
Event::Metric(metric) => metric.0[1],
})
.sum()
}
fn count_tinyvec(events: EventsTinyVec) -> u64 {
events
.into_iter()
.map(|event| match event {
Event::Log(log) => log.0[1],
Event::Metric(metric) => metric.0[1],
})
.sum()
}
fn timeit<T: 'static + Measurement>(crit: &mut Criterion<T>) {
dbg!(size_of::<Event>());
dbg!(size_of::<EventsVec>());
dbg!(size_of::<EventsSmallVec>());
dbg!(size_of::<EventsTinyVec>());
let mut group = crit.benchmark_group("Creation");
for size in [1, 2, 4, 8, 16] {
group.bench_with_input(BenchmarkId::new("Vec", size), &size, |bencher, &size| {
bencher.iter(|| drop(make_vec(size)))
});
group.bench_with_input(BenchmarkId::new("SV", size), &size, |bencher, &size| {
bencher.iter(|| drop(make_smallvec(size)))
});
group.bench_with_input(BenchmarkId::new("TV", size), &size, |bencher, &size| {
bencher.iter(|| drop(make_tinyvec(size)))
});
}
group.finish();
let mut group = crit.benchmark_group("Iterator");
for size in [1, 2, 4, 8, 16] {
group.bench_with_input(BenchmarkId::new("Vec", size), &size, |bencher, &size| {
bencher.iter(|| count_vec(make_vec(size)))
});
group.bench_with_input(BenchmarkId::new("SV", size), &size, |bencher, &size| {
bencher.iter(|| count_smallvec(make_smallvec(size)))
});
group.bench_with_input(BenchmarkId::new("TV", size), &size, |bencher, &size| {
bencher.iter(|| count_tinyvec(make_tinyvec(size)))
});
}
group.finish();
}
criterion_group!(
name = benches;
config = Criterion::default().with_measurement(PerfMeasurement::new(PerfMode::Cycles));
//config = Criterion::default().with_measurement(WallTime);
targets = timeit
);
criterion_main!(benches);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment