From 06b46e935589117ac4583b6ca0d2a3020eb1c6b4 Mon Sep 17 00:00:00 2001 From: QuarticCat Date: Wed, 28 Sep 2022 00:24:18 +0800 Subject: [PATCH 1/6] Enable thin-LTO --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 8eebd7322..d1cc8ee7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ version_check = "0.9.4" # # https://doc.rust-lang.org/cargo/reference/profiles.html#release debug = false +lto = "thin" [[bin]] name = "difft" From d48ee2dfdb59e98c71ce8fd99933268a1eee56ee Mon Sep 17 00:00:00 2001 From: QuarticCat Date: Wed, 28 Sep 2022 04:08:42 +0800 Subject: [PATCH 2/6] Use a faster stack impl --- Cargo.lock | 25 ------------------------ Cargo.toml | 1 - src/diff/graph.rs | 6 ++++-- src/diff/mod.rs | 1 + src/diff/stack.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 28 deletions(-) create mode 100644 src/diff/stack.rs diff --git a/Cargo.lock b/Cargo.lock index b0e14dbe7..794b75ed0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,15 +20,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "archery" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a8da9bc4c4053ee067669762bcaeea6e241841295a2b6c948312dad6ef4cc02" -dependencies = [ - "static_assertions", -] - [[package]] name = "atty" version = "0.2.14" @@ -204,7 +195,6 @@ dependencies = [ "radix-heap", "rayon", "regex", - "rpds", "rustc-hash", "strsim", "term_size", @@ -535,15 +525,6 @@ version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" -[[package]] -name = "rpds" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054e417ded02a19ae192c8c89412eaec7d1c2cdd826aa412565761d86ca6315e" -dependencies = [ - "archery", -] - [[package]] name = "rustc-hash" version = "1.1.0" @@ -579,12 +560,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "strsim" version = "0.10.0" diff --git a/Cargo.toml b/Cargo.toml index d1cc8ee7a..b3db13bf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,6 @@ walkdir = "2.3.2" terminal_size = "0.2.1" const_format = "0.2.22" owo-colors = "3.3.0" -rpds = "0.10.0" wu-diff = "0.1.2" rayon = "1.5.2" tree_magic_mini = "3.0.3" diff --git a/src/diff/graph.rs b/src/diff/graph.rs index db00be25c..f68e65556 100644 --- a/src/diff/graph.rs +++ b/src/diff/graph.rs @@ -1,7 +1,6 @@ //! A graph representation for computing tree diffs. use bumpalo::Bump; -use rpds::Stack; use rustc_hash::FxHashMap; use std::{ cell::RefCell, @@ -12,7 +11,10 @@ use std::{ use strsim::normalized_levenshtein; use crate::{ - diff::changes::{insert_deep_unchanged, ChangeKind, ChangeMap}, + diff::{ + changes::{insert_deep_unchanged, ChangeKind, ChangeMap}, + stack::Stack, + }, parse::syntax::{AtomKind, Syntax, SyntaxId}, }; use Edge::*; diff --git a/src/diff/mod.rs b/src/diff/mod.rs index 44f10e6c7..4bd7efd03 100644 --- a/src/diff/mod.rs +++ b/src/diff/mod.rs @@ -3,4 +3,5 @@ pub mod dijkstra; mod graph; pub mod myers_diff; pub mod sliders; +mod stack; pub mod unchanged; diff --git a/src/diff/stack.rs b/src/diff/stack.rs new file mode 100644 index 000000000..6bf35de1d --- /dev/null +++ b/src/diff/stack.rs @@ -0,0 +1,48 @@ +use std::rc::Rc; + +#[derive(Debug, Clone, Default, PartialEq, Eq)] +struct Node { + val: T, + next: Option>>, +} + +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub struct Stack { + head: Option>>, + len: usize, +} + +impl Stack { + pub fn new() -> Self { + Self { head: None, len: 0 } + } + + pub fn peek(&self) -> Option<&T> { + self.head.as_deref().map(|n| &n.val) + } + + pub fn pop(&self) -> Option> { + self.head.as_deref().map(|n| Self { + head: n.next.clone(), + len: self.len - 1, + }) + } + + pub fn push(&self, v: T) -> Stack { + Self { + head: Some(Rc::new(Node { + val: v, + next: self.head.clone(), + })), + len: self.len + 1, + } + } + + pub fn size(&self) -> usize { + self.len + } + + pub fn is_empty(&self) -> bool { + self.len == 0 + } +} From fa44d4cd5afbf3640be90486a18efd5af0d113e2 Mon Sep 17 00:00:00 2001 From: QuarticCat Date: Wed, 28 Sep 2022 05:36:08 +0800 Subject: [PATCH 3/6] Fix the clippy::clone_double_ref warning --- src/diff/dijkstra.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diff/dijkstra.rs b/src/diff/dijkstra.rs index a8a388331..559fad45a 100644 --- a/src/diff/dijkstra.rs +++ b/src/diff/dijkstra.rs @@ -91,7 +91,7 @@ fn shortest_path_with_edges<'a, 'b>( for vertex in route.iter().skip(1) { let edge = edge_between(prev, vertex); - res.push((edge, prev.clone())); + res.push((edge, *prev)); cost += edge.cost(); prev = vertex; From 2c6972c1b2b8e725ef4cd9887cdf937af60dcaf6 Mon Sep 17 00:00:00 2001 From: QuarticCat Date: Wed, 28 Sep 2022 05:43:35 +0800 Subject: [PATCH 4/6] Fix more clippy warnings --- src/diff/graph.rs | 2 +- src/display/style.rs | 2 +- src/main.rs | 11 +++++------ src/parse/guess_language.rs | 2 +- src/parse/syntax.rs | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/diff/graph.rs b/src/diff/graph.rs index f68e65556..40020ca5e 100644 --- a/src/diff/graph.rs +++ b/src/diff/graph.rs @@ -731,7 +731,7 @@ pub fn get_set_neighbours<'syn, 'b>( } } assert!( - res.len() > 0, + !res.is_empty(), "Must always find some next steps if node is not the end" ); diff --git a/src/display/style.rs b/src/display/style.rs index f7a81264a..aa6ba4bfe 100644 --- a/src/display/style.rs +++ b/src/display/style.rs @@ -130,7 +130,7 @@ pub fn split_and_apply( let end_col = span.end_col as usize; // The remaining spans are beyond the end of this line_part. - if start_col >= part_start + byte_len(&line_part) { + if start_col >= part_start + byte_len(line_part) { break; } diff --git a/src/main.rs b/src/main.rs index 415f48917..f039828e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -55,7 +55,6 @@ use diff::sliders::fix_all_sliders; use options::{DisplayMode, DisplayOptions, FileArgument, Mode, DEFAULT_TAB_WIDTH}; use owo_colors::OwoColorize; use rayon::prelude::*; -use std::path::PathBuf; use std::{env, path::Path}; use summary::{DiffResult, FileContent}; use syntax::init_next_prev; @@ -142,7 +141,7 @@ fn main() { print!("{}", name); let mut extensions: Vec<&str> = (*extensions).into(); - extensions.sort(); + extensions.sort_unstable(); for extension in extensions { print!(" .{}", extension); @@ -179,8 +178,8 @@ fn main() { options::FileArgument::NamedPath(rhs_path), ) if lhs_path.is_dir() && rhs_path.is_dir() => { diff_directories( - &lhs_path, - &rhs_path, + lhs_path, + rhs_path, &display_options, graph_limit, byte_limit, @@ -403,8 +402,8 @@ fn diff_file_content( /// When more than one file is modified, the hg extdiff extension passes directory /// paths with the all the modified files. fn diff_directories<'a>( - lhs_dir: &'a PathBuf, - rhs_dir: &'a PathBuf, + lhs_dir: &'a Path, + rhs_dir: &'a Path, display_options: &DisplayOptions, graph_limit: usize, byte_limit: usize, diff --git a/src/parse/guess_language.rs b/src/parse/guess_language.rs index 23c3eec2c..a82831144 100644 --- a/src/parse/guess_language.rs +++ b/src/parse/guess_language.rs @@ -120,7 +120,7 @@ pub fn language_name(language: Language) -> &'static str { } } -pub const LANG_EXTENSIONS: &'static [(Language, &[&str])] = &[ +pub const LANG_EXTENSIONS: &[(Language, &[&str])] = &[ ( Bash, &[ diff --git a/src/parse/syntax.rs b/src/parse/syntax.rs index bc5f8d7fc..b1829fbeb 100644 --- a/src/parse/syntax.rs +++ b/src/parse/syntax.rs @@ -246,7 +246,7 @@ impl<'a> Syntax<'a> { ) -> &'a Syntax<'a> { // If a parser hasn't cleaned up \r on CRLF files with // comments, discard it. - if content.ends_with("\r") { + if content.ends_with('\r') { content = &content[..content.len() - 1]; } From 3b0edb43a1f79637e7d85073d111239e49fd5034 Mon Sep 17 00:00:00 2001 From: QuarticCat Date: Wed, 28 Sep 2022 05:56:53 +0800 Subject: [PATCH 5/6] Change a RefCell in Vertex to Cell --- src/diff/dijkstra.rs | 6 +++--- src/diff/graph.rs | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/diff/dijkstra.rs b/src/diff/dijkstra.rs index 559fad45a..f9313c12f 100644 --- a/src/diff/dijkstra.rs +++ b/src/diff/dijkstra.rs @@ -44,8 +44,8 @@ fn shortest_vertex_path<'a, 'b>( let (edge, next) = neighbour; let distance_to_next = distance + edge.cost(); - let found_shorter_route = match &*next.predecessor.borrow() { - Some((prev_shortest, _)) => distance_to_next < *prev_shortest, + let found_shorter_route = match next.predecessor.get() { + Some((prev_shortest, _)) => distance_to_next < prev_shortest, None => true, }; @@ -74,7 +74,7 @@ fn shortest_vertex_path<'a, 'b>( let mut vertex_route: Vec<&'b Vertex<'a, 'b>> = vec![]; while let Some((_, node)) = current { vertex_route.push(node); - current = *node.predecessor.borrow(); + current = node.predecessor.get(); } vertex_route.reverse(); diff --git a/src/diff/graph.rs b/src/diff/graph.rs index 40020ca5e..23f9c3063 100644 --- a/src/diff/graph.rs +++ b/src/diff/graph.rs @@ -3,7 +3,7 @@ use bumpalo::Bump; use rustc_hash::FxHashMap; use std::{ - cell::RefCell, + cell::{Cell, RefCell}, cmp::min, fmt, hash::{Hash, Hasher}, @@ -50,7 +50,7 @@ use Edge::*; #[derive(Debug, Clone)] pub struct Vertex<'a, 'b> { pub neighbours: RefCell)>>>, - pub predecessor: RefCell)>>, + pub predecessor: Cell)>>, pub lhs_syntax: Option<&'a Syntax<'a>>, pub rhs_syntax: Option<&'a Syntax<'a>>, parents: Stack>, @@ -260,7 +260,7 @@ impl<'a, 'b> Vertex<'a, 'b> { let parents = Stack::new(); Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax, rhs_syntax, parents, @@ -444,7 +444,7 @@ pub fn get_set_neighbours<'syn, 'b>( allocate_if_new( Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax: lhs_parent.next_sibling(), rhs_syntax: rhs_parent.next_sibling(), can_pop_either: can_pop_either_parent(&parents_next), @@ -469,7 +469,7 @@ pub fn get_set_neighbours<'syn, 'b>( allocate_if_new( Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax: lhs_parent.next_sibling(), rhs_syntax: v.rhs_syntax, can_pop_either: can_pop_either_parent(&parents_next), @@ -494,7 +494,7 @@ pub fn get_set_neighbours<'syn, 'b>( allocate_if_new( Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax: v.lhs_syntax, rhs_syntax: rhs_parent.next_sibling(), can_pop_either: can_pop_either_parent(&parents_next), @@ -521,7 +521,7 @@ pub fn get_set_neighbours<'syn, 'b>( allocate_if_new( Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax: lhs_syntax.next_sibling(), rhs_syntax: rhs_syntax.next_sibling(), parents: v.parents.clone(), @@ -567,7 +567,7 @@ pub fn get_set_neighbours<'syn, 'b>( allocate_if_new( Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax: lhs_next, rhs_syntax: rhs_next, parents: parents_next, @@ -605,7 +605,7 @@ pub fn get_set_neighbours<'syn, 'b>( allocate_if_new( Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax: lhs_syntax.next_sibling(), rhs_syntax: rhs_syntax.next_sibling(), parents: v.parents.clone(), @@ -635,7 +635,7 @@ pub fn get_set_neighbours<'syn, 'b>( allocate_if_new( Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax: lhs_syntax.next_sibling(), rhs_syntax: v.rhs_syntax, parents: v.parents.clone(), @@ -661,7 +661,7 @@ pub fn get_set_neighbours<'syn, 'b>( allocate_if_new( Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax: lhs_next, rhs_syntax: v.rhs_syntax, parents: parents_next, @@ -689,7 +689,7 @@ pub fn get_set_neighbours<'syn, 'b>( allocate_if_new( Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax: v.lhs_syntax, rhs_syntax: rhs_syntax.next_sibling(), parents: v.parents.clone(), @@ -715,7 +715,7 @@ pub fn get_set_neighbours<'syn, 'b>( allocate_if_new( Vertex { neighbours: RefCell::new(None), - predecessor: RefCell::new(None), + predecessor: Cell::new(None), lhs_syntax: v.lhs_syntax, rhs_syntax: rhs_next, parents: parents_next, From b88625d09b9f2641dcd4519ce538aebe6f648322 Mon Sep 17 00:00:00 2001 From: QuarticCat Date: Wed, 28 Sep 2022 20:07:36 +0800 Subject: [PATCH 6/6] Further simplify stack --- src/diff/stack.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/diff/stack.rs b/src/diff/stack.rs index 6bf35de1d..b366937a4 100644 --- a/src/diff/stack.rs +++ b/src/diff/stack.rs @@ -9,12 +9,11 @@ struct Node { #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct Stack { head: Option>>, - len: usize, } impl Stack { pub fn new() -> Self { - Self { head: None, len: 0 } + Self { head: None } } pub fn peek(&self) -> Option<&T> { @@ -24,7 +23,6 @@ impl Stack { pub fn pop(&self) -> Option> { self.head.as_deref().map(|n| Self { head: n.next.clone(), - len: self.len - 1, }) } @@ -34,15 +32,21 @@ impl Stack { val: v, next: self.head.clone(), })), - len: self.len + 1, } } + // O(n) pub fn size(&self) -> usize { - self.len + let mut res = 0; + let mut node = &self.head; + while let Some(next) = node { + res += 1; + node = &next.next; + } + res } pub fn is_empty(&self) -> bool { - self.len == 0 + self.head.is_none() } }