Skip to content

Commit

Permalink
Add a benchmark for the derive macros
Browse files Browse the repository at this point in the history
  • Loading branch information
shahn committed Jan 5, 2025
1 parent 667c196 commit 3531401
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ path = "benches/strings.rs"
harness = false
test = true

[[bench]]
name = "derive"
path = "benches/derive.rs"
harness = false

[dependencies]
bitvec.workspace = true
bytes = { version = "1.7.2", default-features = false }
Expand Down Expand Up @@ -106,3 +111,7 @@ rustls-webpki = "0.102.8"
x509-cert = "0.2.5"
x509-certificate = "0.23.1"
x509-parser = "0.16"
proc-macro2 = "1.0.86"
quote = "1.0.37"
rasn-derive-impl = { path = "macros/macros_impl"}
syn = { version = "2.0.87", features = ["full"] }
109 changes: 109 additions & 0 deletions benches/derive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use criterion::{black_box, criterion_group, criterion_main, BatchSize, Criterion};
use quote::ToTokens;
use std::ffi::OsStr;
use std::fs;
use std::path::PathBuf;
use syn::DeriveInput;

fn recurse_dir(path: &PathBuf, prefix: &PathBuf, files: &mut Vec<(String, Vec<DeriveInput>)>) {
for file in
fs::read_dir(path).unwrap_or_else(|_| panic!("Unable to recurse into dir {:?}", path))
{
let Ok(file) = file else {
panic!("Unable to read dir entry inside {:?}", path);
};
if file
.metadata()
.unwrap_or_else(|_| panic!("Unable to read file {:?} metadata", file.path()))
.is_dir()
{
recurse_dir(&file.path(), prefix, files);
} else if Some(OsStr::new("rs")) == file.path().extension() {
let name = file
.path()
.to_string_lossy()
.into_owned()
.trim_start_matches(&*prefix.to_string_lossy())
.to_string();
let content = fs::read_to_string(file.path())
.unwrap_or_else(|_| panic!("Unable to read file {:?}", file.path()));
let parsed = syn::parse_file(&content)
.unwrap_or_else(|_| panic!("Unable to parse file {:?}", file.path()));
let interesting_items: Vec<_> = parsed
.items
.iter()
.filter(|item| match item {
syn::Item::Enum(e) => check_attrs(&e.attrs),
syn::Item::Struct(s) => check_attrs(&s.attrs),
_ => false,
})
.map(|item| syn::parse2(item.to_token_stream()).unwrap())
.collect();
if !interesting_items.is_empty() {
files.push((name, interesting_items));
}
}
}
}

fn check_attrs(attrs: &[syn::Attribute]) -> bool {
for attr in attrs {
if !attr.path().is_ident("derive") {
continue;
}
let mut attr_found = false;
attr.parse_nested_meta(|meta| {
if meta.path.is_ident("AsnType")
|| meta.path.is_ident("Encode")
|| meta.path.is_ident("Decode")
{
attr_found = true;
}
Ok(())
})
.unwrap();
if attr_found {
return true;
}
}
false
}

macro_rules! derive_bench {
($bench_name:ident, $name:literal, $fn:ident ) => {
fn $bench_name(c: &mut Criterion) {
let crate_root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut files = Vec::new();
recurse_dir(&crate_root_dir, &crate_root_dir, &mut files);

let mut group = c.benchmark_group($name);

for (filename, items) in files {
group.bench_function(filename, |b| {
b.iter_batched(
|| items.clone(),
|data| {
for x in data {
let _ = black_box(rasn_derive_impl::$fn(x));
}
},
BatchSize::SmallInput,
)
});
}

group.finish();
}
};
}

derive_bench!(derive_asntype, "derive_asntype", asn_type_derive_inner);
derive_bench!(derive_decode, "derive_decode", decode_derive_inner);
derive_bench!(derive_encode, "derive_encode", encode_derive_inner);

criterion_group!(
name = derive;
config = Criterion::default().sample_size(200);
targets = derive_encode, derive_decode, derive_asntype
);
criterion_main!(derive);

0 comments on commit 3531401

Please sign in to comment.