Use Myers' diff everywhere

The diff crate has a great ergonomic API, but it doesn't implement
Myers' algorithm and performs badly on large inputs.

https://github.com/utkarshkukreti/diff.rs/issues/1

Now that we have a wrapper wu_diff that provides a similar API,
replace the remaining call sites to diff::slice(). These are
relatively cold, so this is a small performance improvement (1%
instruction reduction).
pull/166/head
Wilfred Hughes 2022-03-12 12:29:34 +07:00
parent dbf088bd25
commit dad463daf5
4 changed files with 11 additions and 11 deletions

1
Cargo.lock generated

@ -168,7 +168,6 @@ dependencies = [
"cc",
"clap",
"const_format",
"diff",
"itertools",
"lazy_static",
"libc",

@ -22,7 +22,6 @@ include = [
[dependencies]
regex = "1.5.4"
diff = "0.1.12"
clap = { version = "3.0.13", features = ["cargo"] }
itertools = "0.10.1"
typed-arena = "2.0.1"

@ -12,6 +12,7 @@ use typed_arena::Arena;
use crate::{
lines::{LineNumber, NewlinePositions},
myers_diff,
positions::SingleLineSpan,
};
use ChangeKind::*;
@ -632,9 +633,9 @@ fn split_comment_words(
let mut opposite_offset = 0;
let mut res = vec![];
for diff_res in diff::slice(&content_parts, &other_parts) {
for diff_res in myers_diff::slice(&content_parts, &other_parts) {
match diff_res {
diff::Result::Left(word) => {
myers_diff::DiffResult::Left(word) => {
// This word is novel to this side.
res.push(MatchedPos {
kind: MatchKind::NovelWord {
@ -648,7 +649,7 @@ fn split_comment_words(
});
offset += word.len();
}
diff::Result::Both(word, opposite_word) => {
myers_diff::DiffResult::Both(word, opposite_word) => {
// This word is present on both sides.
let word_pos =
content_newlines.from_offsets_relative_to(pos, offset, offset + word.len())[0];
@ -669,7 +670,7 @@ fn split_comment_words(
offset += word.len();
opposite_offset += opposite_word.len();
}
diff::Result::Right(opposite_word) => {
myers_diff::DiffResult::Right(opposite_word) => {
// Only exists on other side, nothing to do on this side.
opposite_offset += opposite_word.len();
}

@ -1,3 +1,4 @@
use crate::myers_diff;
use crate::syntax::{ChangeKind, Syntax};
const TINY_TREE_THRESHOLD: u32 = 10;
@ -50,9 +51,9 @@ fn mark_unchanged_toplevel<'a>(
let mut section_lhs_nodes = vec![];
let mut section_rhs_nodes = vec![];
for diff_res in diff::slice(&lhs_node_ids, &rhs_node_ids) {
for diff_res in myers_diff::slice(&lhs_node_ids, &rhs_node_ids) {
match diff_res {
diff::Result::Both(lhs, rhs) => {
myers_diff::DiffResult::Both(lhs, rhs) => {
let lhs_node = lhs.1;
let rhs_node = rhs.1;
@ -91,10 +92,10 @@ fn mark_unchanged_toplevel<'a>(
rhs_node.set_change_deep(ChangeKind::Unchanged(lhs_node));
}
}
diff::Result::Left(lhs) => {
myers_diff::DiffResult::Left(lhs) => {
section_lhs_nodes.push(lhs.1);
}
diff::Result::Right(rhs) => {
myers_diff::DiffResult::Right(rhs) => {
section_rhs_nodes.push(rhs.1);
}
}
@ -147,7 +148,7 @@ fn mark_unchanged_outer_list<'a>(
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
struct EqOnFirstItem<X, Y>(X, Y);
impl<X: Eq, Y> PartialEq for EqOnFirstItem<X, Y> {