use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use jomini::{
common::Date, BinaryDeserializer, BinaryTape, Scalar, TextDeserializer, TextTape, Utf8Encoding,
Windows1252Encoding,
};
use std::collections::HashMap;
const METADATA_BIN: &'static [u8] = include_bytes!("../tests/fixtures/meta.bin");
const METADATA_TXT: &'static [u8] = include_bytes!("../tests/fixtures/meta.txt");
const CK3_BIN: &'static [u8] = include_bytes!("../tests/fixtures/ck3-header.bin");
const CK3_TXT: &'static [u8] = include_bytes!("../tests/fixtures/ck3-header.txt");
pub fn is_ascii_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("is_ascii");
for size in [1, 4, 8, 16, 32, 64, 128, 256, 512].iter() {
let data = vec![b'a'; *size as usize];
group.throughput(Throughput::Bytes(*size as u64));
group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &_size| {
b.iter(|| Scalar::new(black_box(&data)).is_ascii());
});
}
group.finish();
}
pub fn windows1252_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("windows1252");
for size in [2, 4, 8, 16, 32, 64, 128, 256, 512].iter() {
let data = vec![b'a'; *size as usize];
let data2 = vec![0xfe; *size as usize];
group.throughput(Throughput::Bytes(*size as u64));
group.bench_with_input(
BenchmarkId::new("ascii-to-utf8", size),
size,
|b, &_size| b.iter(|| Windows1252Encoding::decode(&data)),
);
group.bench_with_input(BenchmarkId::new("1252-to-utf8", size), size, |b, &_size| {
b.iter(|| Windows1252Encoding::decode(&data2))
});
}
group.finish();
}
pub fn utf8_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("utf8");
for size in [2, 4, 8, 16, 32, 64, 128, 256, 512].iter() {
let mut ascii_str = String::with_capacity(*size as usize);
let mut utf8_str = String::with_capacity(*size / 2 as usize);
for _ in 0..*size {
ascii_str.push('a');
}
for _ in 0..size / 2 {
utf8_str.push('Ã¥');
}
let data = ascii_str.as_bytes();
let data2 = utf8_str.as_bytes();
group.throughput(Throughput::Bytes(*size as u64));
group.bench_with_input(
BenchmarkId::new("ascii-to-utf8", size),
size,
|b, &_size| b.iter(|| Utf8Encoding::decode(&data)),
);
group.bench_with_input(BenchmarkId::new("utf8-to-utf8", size), size, |b, &_size| {
b.iter(|| Utf8Encoding::decode(&data2))
});
}
group.finish();
}
pub fn to_u64_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("to_u64");
for input in [&b"1444"[..], &b"20405029"[..]].iter() {
let data = Scalar::new(input);
let ins = std::str::from_utf8(input).unwrap();
group.bench_with_input(BenchmarkId::from_parameter(ins), &data, |b, &data| {
b.iter(|| black_box(data.to_u64().unwrap()))
});
}
group.finish();
}
pub fn to_f64_benchmark(c: &mut Criterion) {
c.bench_function("to_f64", |b| {
b.iter(|| Scalar::new(b"20405029.125").to_f64())
});
}
pub fn binary_deserialize_benchmark(c: &mut Criterion) {
#[derive(serde::Deserialize, PartialEq, Eq, Debug)]
struct Meta {
campaign_id: String,
}
let data = &METADATA_BIN["EU4bin".len()..];
let mut group = c.benchmark_group("deserialize");
let mut map = HashMap::new();
map.insert(0x337f, "campaign_id");
group.throughput(Throughput::Bytes(data.len() as u64));
group.bench_function("binary", |b| {
b.iter(|| {
let _res: Meta = BinaryDeserializer::eu4_builder()
.from_slice(&data[..], &map)
.unwrap();
})
});
group.finish();
}
pub fn text_deserialize_benchmark(c: &mut Criterion) {
#[derive(serde::Deserialize, PartialEq, Eq, Debug)]
struct Meta {
campaign_id: String,
}
let data = &METADATA_TXT["EU4txt".len()..];
let mut group = c.benchmark_group("deserialize");
group.throughput(Throughput::Bytes(data.len() as u64));
group.bench_function("text", |b| {
b.iter(|| {
let _res: Meta = TextDeserializer::from_windows1252_slice(&data[..]).unwrap();
})
});
group.finish();
}
pub fn binary_parse_benchmark(c: &mut Criterion) {
let data = &METADATA_BIN["EU4bin".len()..];
let mut group = c.benchmark_group("parse");
group.throughput(Throughput::Bytes(data.len() as u64));
group.bench_function(BenchmarkId::new("binary", "eu4"), |b| {
let mut tape = BinaryTape::default();
b.iter(move || {
BinaryTape::eu4_parser()
.parse_slice_into_tape(&data[..], &mut tape)
.unwrap();
})
});
let data = &CK3_BIN[..];
group.throughput(Throughput::Bytes(data.len() as u64));
group.bench_function(BenchmarkId::new("binary", "ck3"), |b| {
let mut tape = BinaryTape::default();
b.iter(move || {
BinaryTape::eu4_parser()
.parse_slice_into_tape(&data[..], &mut tape)
.unwrap();
})
});
group.finish();
}
pub fn text_parse_benchmark(c: &mut Criterion) {
let data = &METADATA_TXT["EU4txt".len()..];
let mut group = c.benchmark_group("parse");
group.throughput(Throughput::Bytes(data.len() as u64));
group.bench_function(BenchmarkId::new("text", "eu4"), |b| {
let mut tape = TextTape::default();
b.iter(|| {
TextTape::parser()
.parse_slice_into_tape(&data[..], &mut tape)
.unwrap();
})
});
let data = &CK3_TXT[..];
group.throughput(Throughput::Bytes(data.len() as u64));
group.bench_function(BenchmarkId::new("text", "ck3"), |b| {
let mut tape = TextTape::default();
b.iter(|| {
TextTape::parser()
.parse_slice_into_tape(&data[..], &mut tape)
.unwrap();
})
});
group.finish();
}
pub fn date_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("eu4date-parse");
group.bench_function("valid-date", |b| {
b.iter(|| Date::parse_from_str("1444.11.11").unwrap())
});
group.bench_function("invalid-date", |b| {
b.iter(|| Date::parse_from_str("marketplace").is_none())
});
group.bench_function("long-invalid-date", |b| {
b.iter(|| Date::parse_from_str("incidents_bur_inheritance.5").is_none())
});
group.finish();
}
criterion_group!(
benches,
is_ascii_benchmark,
utf8_benchmark,
windows1252_benchmark,
binary_parse_benchmark,
text_parse_benchmark,
binary_deserialize_benchmark,
text_deserialize_benchmark,
to_u64_benchmark,
to_f64_benchmark,
date_benchmark,
);
criterion_main!(benches);