Skip to content

Commit 0f0aa58

Browse files
optimize diffing input with long matching prefix, see #15
The benchmark in this commit speeds up from ~360us to ~210us.
1 parent 782d454 commit 0f0aa58

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

benches/benches.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ extern crate diff;
33

44
use criterion::Criterion;
55

6-
criterion::criterion_group!(benches, bench_slice);
6+
criterion::criterion_group!(benches, bench_slice, bench_chars);
77
criterion::criterion_main!(benches);
88

99
fn bench_slice(c: &mut Criterion) {
@@ -42,3 +42,12 @@ fn bench_slice(c: &mut Criterion) {
4242
b.iter(|| ::diff::slice(&left, &right));
4343
});
4444
}
45+
46+
fn bench_chars(c: &mut Criterion) {
47+
c.bench_function("1024 byte string, last 256 different", |b| {
48+
let left = "?".repeat(768) + &"_".repeat(256);
49+
let right = "?".repeat(768) + &"!".repeat(256);
50+
assert_eq!(left.len(), right.len());
51+
b.iter(|| ::diff::chars(&left, &right));
52+
});
53+
}

src/lib.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ where
6767
let table: Vec<Vec<u32>> = {
6868
let mut table = vec![vec![0; right_diff_size + 1]; left_diff_size + 1];
6969
let left_skip = left.clone().skip(leading_equals).take(left_diff_size);
70-
let right_skip = right.clone().skip(leading_equals).take(right_diff_size);
70+
let right_skip = advance_by(right.clone(), leading_equals).take(right_diff_size);
7171

7272
for (i, l) in left_skip.clone().enumerate() {
7373
for (j, r) in right_skip.clone().enumerate() {
@@ -126,3 +126,11 @@ where
126126

127127
total_diff
128128
}
129+
130+
#[inline]
131+
fn advance_by<I: Iterator>(mut iter: I, by: usize) -> I {
132+
for _ in 0..by {
133+
iter.next();
134+
}
135+
iter
136+
}

0 commit comments

Comments
 (0)