mirror of
https://github.com/simonask/libyaml-safer
synced 2025-02-16 12:28:30 +00:00
122 lines
4.6 KiB
Rust
122 lines
4.6 KiB
Rust
use std::mem::MaybeUninit;
|
|
|
|
use criterion::{criterion_group, criterion_main, Criterion};
|
|
use libyaml_safer::{Document, Emitter, Parser};
|
|
use unsafe_libyaml::*;
|
|
|
|
static VERY_LARGE_YAML: &[u8] = include_bytes!("very_large.yml");
|
|
|
|
pub fn parser(c: &mut Criterion) {
|
|
c.bench_function("libyaml-safer parse large", |b| {
|
|
// Note: Not using `iter_with_large_drop` because that would be unfair
|
|
// to unsafe-libyaml, which needs a call to `yaml_document_delete`.
|
|
b.iter(|| {
|
|
let mut input = VERY_LARGE_YAML;
|
|
let mut parser = Parser::new();
|
|
parser.set_input(&mut input);
|
|
Document::load(&mut parser)
|
|
})
|
|
});
|
|
|
|
c.bench_function("unsafe-libyaml parse large", |b| {
|
|
b.iter(|| unsafe {
|
|
let mut parser = MaybeUninit::zeroed();
|
|
if !yaml_parser_initialize(parser.as_mut_ptr()).ok {
|
|
panic!("yaml_parser_initialize failed");
|
|
}
|
|
let mut parser = parser.assume_init();
|
|
yaml_parser_set_input_string(
|
|
&mut parser,
|
|
VERY_LARGE_YAML.as_ptr(),
|
|
VERY_LARGE_YAML.len() as _,
|
|
);
|
|
let mut document = MaybeUninit::zeroed();
|
|
if !yaml_parser_load(&mut parser, document.as_mut_ptr()).ok {
|
|
panic!("yaml_parser_load faled");
|
|
};
|
|
yaml_document_delete(document.as_mut_ptr());
|
|
yaml_parser_delete(&mut parser);
|
|
})
|
|
});
|
|
|
|
c.bench_function("libyaml-safer emit large", |b| {
|
|
// output shouldn't be much larger than the input, but just to be safe...
|
|
let mut buffer = Vec::with_capacity(VERY_LARGE_YAML.len());
|
|
|
|
let doc = {
|
|
let mut parser = Parser::new();
|
|
let mut input = VERY_LARGE_YAML;
|
|
parser.set_input(&mut input);
|
|
Document::load(&mut parser).unwrap()
|
|
};
|
|
|
|
b.iter_custom(|iters| {
|
|
let mut measurement = std::time::Duration::ZERO;
|
|
for _ in 0..iters {
|
|
let doc = doc.clone();
|
|
let start_time = std::time::Instant::now();
|
|
let mut emitter = Emitter::new();
|
|
emitter.set_output(&mut buffer);
|
|
doc.dump(&mut emitter).unwrap();
|
|
measurement += start_time.elapsed();
|
|
}
|
|
measurement
|
|
});
|
|
});
|
|
|
|
c.bench_function("unsafe-libyaml emit large", |b| {
|
|
// output shouldn't be much larger than the input, but just to be safe...
|
|
let mut buffer = vec![0; VERY_LARGE_YAML.len() * 2];
|
|
|
|
// `yaml_document_t` cannot be cloned, so we have to parse it every iteration unfortunately.
|
|
let read_doc = || unsafe {
|
|
let mut parser = MaybeUninit::zeroed();
|
|
if !yaml_parser_initialize(parser.as_mut_ptr()).ok {
|
|
panic!("yaml_parser_initialize failed");
|
|
}
|
|
let mut parser = parser.assume_init();
|
|
yaml_parser_set_input_string(
|
|
&mut parser,
|
|
VERY_LARGE_YAML.as_ptr(),
|
|
VERY_LARGE_YAML.len() as _,
|
|
);
|
|
let mut document = MaybeUninit::zeroed();
|
|
if !yaml_parser_load(&mut parser, document.as_mut_ptr()).ok {
|
|
panic!("yaml_parser_load faled");
|
|
};
|
|
yaml_parser_delete(&mut parser);
|
|
document.assume_init()
|
|
};
|
|
|
|
b.iter_custom(|iters| {
|
|
let mut measurement = std::time::Duration::ZERO;
|
|
for _ in 0..iters {
|
|
unsafe {
|
|
let mut doc = read_doc();
|
|
let start_time = std::time::Instant::now();
|
|
let mut emitter = MaybeUninit::zeroed();
|
|
if !yaml_emitter_initialize(emitter.as_mut_ptr()).ok {
|
|
panic!("yaml_emitter_initialize failed");
|
|
}
|
|
let mut emitter = emitter.assume_init();
|
|
let mut size_written = 0;
|
|
yaml_emitter_set_output_string(
|
|
&mut emitter,
|
|
buffer.as_mut_ptr(),
|
|
buffer.len() as _,
|
|
&mut size_written,
|
|
);
|
|
if !yaml_emitter_dump(&mut emitter, &mut doc).ok {
|
|
panic!("yaml_emitter_dump failed");
|
|
}
|
|
measurement += start_time.elapsed();
|
|
yaml_emitter_delete(&mut emitter);
|
|
}
|
|
}
|
|
measurement
|
|
});
|
|
});
|
|
}
|
|
|
|
criterion_group!(benches, parser);
|
|
criterion_main!(benches);
|