Skip to content

Commit

Permalink
Add benchmark for ELF "str2symtab" creation
Browse files Browse the repository at this point in the history
Add a benchmark for the creation of our ELF "str2symtab". This creation
should trigger a good chunk of our data structure traversing and
"parsing" paths. The performance is roughly as follows:

  $ cargo bench --features=nightly -- bench_str2sym_creation
  > test elf::parser::tests::bench_str2sym_creation  ... bench:  26,023,493.50 ns/iter (+/- 644,362.62)

The main reason for the addition of the benchmark is to get an idea how
much performance we lost due to recent ELF parser changes: both the
introduction of 32 bit support as well as the logic for working with
different backends is assumed to have some runtime impact. Backporting
the benchmark on top of commit 4688aa0 ("cli: Rework tracing
output") results in the following performance numbers before said ELF
changes:

  $ cargo bench --features=nightly -- bench_str2sym_creation
  > test elf::parser::tests::bench_str2sym_creation  ... bench:  25,233,120.60 ns/iter (+/- 496,742.81)

The difference is reproducible, but arguably small and acceptable. We
may be able to speed things up a bit more via the usage of smaller
indexes.

Signed-off-by: Daniel Müller <[email protected]>
  • Loading branch information
d-e-s-o committed Dec 27, 2024
1 parent 3f4b694 commit 9d1978e
Showing 1 changed file with 31 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/elf/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,8 @@ mod tests {

use std::env;
use std::env::current_exe;
#[cfg(feature = "nightly")]
use std::hint::black_box;
use std::io::Write as _;
use std::mem::size_of;
use std::slice;
Expand All @@ -1257,6 +1259,9 @@ mod tests {

use test_log::test;

#[cfg(feature = "nightly")]
use test::Bencher;


/// Exercise the `Debug` representation of various types.
#[test]
Expand Down Expand Up @@ -1820,4 +1825,30 @@ mod tests {
let symtab = cache.ensure_symtab().unwrap();
assert!(symtab.is_empty());
}

/// Benchmark creation of our "str2symtab" table.
///
/// Creating this table exercises a lot of the parser code paths and
/// is expected to be a somewhat reasonable approximation of overall
/// end-to-end performance.
#[cfg(feature = "nightly")]
#[bench]
fn bench_str2sym_creation(b: &mut Bencher) {
let path = Path::new(&env!("CARGO_MANIFEST_DIR"))
.join("data")
.join("vmlinux-5.17.12-100.fc34.x86_64.elf");
let parser = ElfParser::open(&path).unwrap();
let mmap = &parser._backend;

// Our memory mapping is created only once and criterion does a
// few warm up runs that should make sure that everything is
// paged in. So we expect to benchmark parsing & data structure
// traversing performance here.

let () = b.iter(|| {
let cache = Cache::new(mmap.deref());
let syms = cache.ensure_str2symtab().unwrap();
let _syms = black_box(syms);
});
}
}

0 comments on commit 9d1978e

Please sign in to comment.