//! Simple benchmarks of glyph parsing.
//!
//! This should be run when making any changes to glyph parsing.
use std::path::Path;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use norad::Glyph;
static MUTATOR_SANS_GLYPHS_DIR: &str = "testdata/MutatorSansLightWide.ufo/glyphs";
static S_GLYPH: &str = "testdata/MutatorSansLightWide.ufo/glyphs/S_.glif";
static DOT: &str = "testdata/MutatorSansLightWide.ufo/glyphs/dot.glif";
static A_ACUTE_GLYPH: &str = "testdata/MutatorSansLightWide.ufo/glyphs/A_acute.glif";
// largest glyph in noto cjk
static CID61855: &str = "testdata/cid61855.glif";
fn load_bytes
(path: P) -> Vec
where
P: AsRef,
{
std::fs::read(path).unwrap()
}
// Load all the .glif files in a directory
fn load_all(dir: &str) -> Vec> {
std::fs::read_dir(dir)
.unwrap()
.map(|e| e.unwrap())
.filter_map(|e| {
e.path().extension().map_or(false, |ext| ext == "glif").then(|| load_bytes(e.path()))
})
.collect()
}
pub fn criterion_benchmark(c: &mut Criterion) {
// a normal glyph
c.bench_function("parse S", |b| {
let bytes = load_bytes(S_GLYPH);
b.iter(|| {
Glyph::parse_raw(black_box(&bytes)).unwrap();
});
});
// a very small glyph
c.bench_function("parse dot", |b| {
let bytes = load_bytes(DOT);
b.iter(|| {
Glyph::parse_raw(black_box(&bytes)).unwrap();
});
});
// a very large glyph
c.bench_function("parse large CJK glyph", |b| {
let bytes = load_bytes(CID61855);
b.iter(|| {
Glyph::parse_raw(black_box(&bytes)).unwrap();
});
});
// a component glyph
c.bench_function("parse A_acute", |b| {
let bytes = load_bytes(A_ACUTE_GLYPH);
b.iter(|| {
Glyph::parse_raw(black_box(&bytes)).unwrap();
});
});
// many glyphs
c.bench_function("parse MutatorSansLightWide glyphs", |b| {
let glyphs = load_all(MUTATOR_SANS_GLYPHS_DIR);
assert!(glyphs.len() > 25, "sanity check");
b.iter(|| {
for glyph_bytes in &glyphs {
Glyph::parse_raw(black_box(glyph_bytes)).unwrap();
}
});
});
// Note to somebody using this:
//
// It might be nice if we also had some other examples, like a glyph with
// a large 'lib' section?
c.bench_function("load S glyph", |b| {
b.iter(|| {
let data = std::fs::read(black_box(S_GLYPH)).unwrap();
// just make sure we can't be optimized away?
assert!(data.len() != 42);
});
});
c.bench_function("load large CJK glyph", |b| {
b.iter(|| {
let data = std::fs::read(black_box(CID61855)).unwrap();
// just make sure we can't be optimized away?
assert!(data.len() != 42);
});
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);