Move to smallvec for seen vertices

This is a surprisingly large perf win. On my Thinkpad:

typing_before/after.ml:
before: 3.038B instructions
after:  2.870B instructions

slow_before/after.rs:
before: 2.381B instructions
after:  1.260B instructions (!)
pull/708/head
Wilfred Hughes 2024-04-28 16:16:47 +07:00
parent 26e1ae40ef
commit d15d593708
4 changed files with 12 additions and 4 deletions

@ -10,6 +10,11 @@ changes.
Difftastic now has a man page, see the `difft.1` file.
### Performance
Fixed a memory leak and substantially improved performance in some
cases (up to 2x in testing).
## 0.57 (released 1st April 2024)
### Parsing

1
Cargo.lock generated

@ -251,6 +251,7 @@ dependencies = [
"rustc-hash",
"serde",
"serde_json",
"smallvec",
"strsim",
"strum",
"tree-sitter",

@ -80,6 +80,7 @@ humansize = "2.1.3"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
line-numbers = "0.3.0"
smallvec = "1.13.2"
[dev-dependencies]
# assert_cmd 2.0.6 requires rust 1.60

@ -7,6 +7,7 @@ use std::{
hash::{Hash, Hasher},
};
use smallvec::{SmallVec, smallvec};
use bumpalo::Bump;
use hashbrown::hash_map::RawEntryMut;
use strsim::normalized_levenshtein;
@ -365,7 +366,7 @@ impl Edge {
fn allocate_if_new<'s, 'b>(
v: Vertex<'s, 'b>,
alloc: &'b Bump,
seen: &mut DftHashMap<&Vertex<'s, 'b>, Vec<&'b Vertex<'s, 'b>>>,
seen: &mut DftHashMap<&Vertex<'s, 'b>, SmallVec<[&'b Vertex<'s, 'b>; 2]>>,
) -> &'b Vertex<'s, 'b> {
// We use the entry API so that we only need to do a single lookup
// for access and insert.
@ -399,11 +400,11 @@ fn allocate_if_new<'s, 'b>(
let allocated = alloc.alloc(v);
// We know that this vec will never have more than 2
// nodes, and this code is very hot, so reserve.
// nodes, and this code is very hot, so use a smallvec.
//
// We still use a vec to enable experiments with the value
// of how many possible parenthesis nestings to explore.
let mut existing: Vec<&'b Vertex<'s, 'b>> = Vec::with_capacity(2);
let mut existing: SmallVec<[&'b Vertex<'s, 'b>; 2]> = smallvec![&*allocated];
existing.push(allocated);
vacant.insert(allocated, existing);
@ -496,7 +497,7 @@ fn pop_all_parents<'s, 'b>(
pub(crate) fn set_neighbours<'s, 'b>(
v: &Vertex<'s, 'b>,
alloc: &'b Bump,
seen: &mut DftHashMap<&Vertex<'s, 'b>, Vec<&'b Vertex<'s, 'b>>>,
seen: &mut DftHashMap<&Vertex<'s, 'b>, SmallVec<[&'b Vertex<'s, 'b>; 2]>>,
) {
if v.neighbours.borrow().is_some() {
return;