diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f580287..0b59616a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Unreleased ---------- - Added support for relocatable ELF and DWARF - Added support for kernel module symbolization with DWARF data +- Improved performance of ELF symbolization - Bumped minimum supported Rust version to `1.88` diff --git a/src/elf/parser.rs b/src/elf/parser.rs index 6d4aa7de..950a95c9 100644 --- a/src/elf/parser.rs +++ b/src/elf/parser.rs @@ -373,18 +373,19 @@ impl<'elf> SymbolTableCache<'elf> { } fn create_by_addr_idx(&self) -> Box<[usize]> { - let mut by_addr_idx = self - .syms - .iter(0) - .enumerate() - // Filter out any symbols that we do not support. - .filter(|(_idx, sym)| sym.matches(SymType::Undefined)) - .map(|(idx, _sym)| idx) - .collect::>(); + let mut by_addr_idx = Vec::with_capacity(self.syms.len()); + let () = by_addr_idx.extend( + self.syms + .iter(0) + .enumerate() + // Filter out any symbols that we do not support. + .filter(|(_idx, sym)| sym.matches(SymType::Undefined)) + .map(|(idx, _sym)| idx), + ); // Order symbols by address and those with equal address descending by // size. - let () = by_addr_idx.sort_by(|idx1, idx2| { + let () = by_addr_idx.sort_unstable_by(|idx1, idx2| { // SANITY: Both indexes originate in our code and are known // to be in bounds. let sym1 = self.syms.get(*idx1).unwrap(); @@ -394,7 +395,7 @@ impl<'elf> SymbolTableCache<'elf> { .then_with(|| sym1.size().cmp(&sym2.size()).reverse()) }); - by_addr_idx + by_addr_idx.into_boxed_slice() } fn ensure_by_addr_idx(&self) -> &[usize] { @@ -431,7 +432,7 @@ impl<'elf> SymbolTableCache<'elf> { }) .collect::>>()?; - let () = str2sym.sort_by_key(|(name, _i)| name.bytes(&self.strs)); + let () = str2sym.sort_unstable_by_key(|(name, _i)| name.bytes(&self.strs)); Ok(str2sym) }