Skip to content

Commit

Permalink
Move to smallvec for seen vertices
Browse files Browse the repository at this point in the history
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 (!)
  • Loading branch information
Wilfred committed Apr 28, 2024
1 parent 26e1ae4 commit d15d593
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 5 additions & 4 deletions src/diff/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit d15d593

Please sign in to comment.