From 8d2fa4ae95b5df2cde1eafbc0f868922d04b8cb8 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sun, 7 Jan 2024 18:56:52 +0100 Subject: [PATCH] fish_indent: fix accidentally quadratic perf regression due to chars().last() Iterator::last() consumes the entire iterator, even for DoubleEndedIterator, see https://github.com/rust-lang/rust/pull/28125#issuecomment-145070161 Because of this, "at_line_start()" took 90% of fish_indent share/completions/git.fish making it take 1000ms instead of 30 ms. Fix that. --- fish-rust/src/common.rs | 2 +- fish-rust/src/fish_indent.rs | 2 +- fish-rust/src/highlight.rs | 2 +- fish-rust/src/path.rs | 2 +- fish-rust/src/reader.rs | 4 ++-- fish-rust/src/wildcard.rs | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fish-rust/src/common.rs b/fish-rust/src/common.rs index 6421863c8..a59be84b7 100644 --- a/fish-rust/src/common.rs +++ b/fish-rust/src/common.rs @@ -545,7 +545,7 @@ enum Mode { // In general, this is ANY_STRING. But as a hack, if the last appended char // is ANY_STRING, delete the last char and store ANY_STRING_RECURSIVE to // reflect the fact that ** is the recursive wildcard. - if result.chars().last() == Some(ANY_STRING) { + if result.chars().next_back() == Some(ANY_STRING) { assert!(!result.is_empty()); result.truncate(result.len() - 1); to_append_or_none = Some(ANY_STRING_RECURSIVE); diff --git a/fish-rust/src/fish_indent.rs b/fish-rust/src/fish_indent.rs index b73fa1a2f..3e645c7c6 100755 --- a/fish-rust/src/fish_indent.rs +++ b/fish-rust/src/fish_indent.rs @@ -319,7 +319,7 @@ fn gap_text_flags_before_node(&self, node: &dyn Node) -> GapFlags { // \return whether we are at the start of a new line. fn at_line_start(&self) -> bool { - self.output.chars().last().is_none_or(|c| c == '\n') + self.output.chars().next_back().is_none_or(|c| c == '\n') } // \return whether we have a space before the output. diff --git a/fish-rust/src/highlight.rs b/fish-rust/src/highlight.rs index 65006c605..a90dbdeb2 100644 --- a/fish-rust/src/highlight.rs +++ b/fish-rust/src/highlight.rs @@ -782,7 +782,7 @@ pub fn is_potential_path( return false; } let mut abs_path = path_apply_working_directory(&clean_potential_path_fragment, wd); - let must_be_full_dir = abs_path.chars().last() == Some('/'); + let must_be_full_dir = abs_path.chars().next_back() == Some('/'); if flags.contains(PathFlags::PATH_FOR_CD) { abs_path = normalize_path(&abs_path, /*allow_leading_double_slashes=*/ true); } diff --git a/fish-rust/src/path.rs b/fish-rust/src/path.rs index 4877a975c..42e62b055 100644 --- a/fish-rust/src/path.rs +++ b/fish-rust/src/path.rs @@ -340,7 +340,7 @@ pub fn path_get_cdpath(dir: &wstr, wd: &wstr, vars: &dyn Environment) -> Option< if dir.is_empty() { return None; } - assert!(wd.chars().last() == Some('/')); + assert!(wd.chars().next_back() == Some('/')); let paths = path_apply_cdpath(dir, wd, vars); for a_dir in paths { diff --git a/fish-rust/src/reader.rs b/fish-rust/src/reader.rs index 78245598c..f0c920ac5 100644 --- a/fish-rust/src/reader.rs +++ b/fish-rust/src/reader.rs @@ -3798,7 +3798,7 @@ fn get_autosuggestion_performer( // Here we do something a little funny. If the line ends with a space, and the cursor is not // at the end, don't use completion autosuggestions. It ends up being pretty weird seeing // stuff get spammed on the right while you go back to edit a line - let last_char = search_string.chars().last().unwrap(); + let last_char = search_string.chars().next_back().unwrap(); let cursor_at_end = cursor_pos == search_string.len(); if !cursor_at_end && last_char.is_whitespace() { return nothing; @@ -4693,7 +4693,7 @@ fn add_to_history(&mut self) { // Historical behavior is to trim trailing spaces, unless escape (#7661). let mut text = self.command_line.text().to_owned(); - while text.chars().last() == Some(' ') + while text.chars().next_back() == Some(' ') && count_preceding_backslashes(&text, text.len() - 1) % 2 == 0 { text.pop(); diff --git a/fish-rust/src/wildcard.rs b/fish-rust/src/wildcard.rs index 82e2c51d8..c150acc46 100644 --- a/fish-rust/src/wildcard.rs +++ b/fish-rust/src/wildcard.rs @@ -632,7 +632,7 @@ pub fn expand(&mut self, base_dir: &wstr, wc: &wstr, effective_prefix: &wstr) { // ANY_STRING_RECURSIVE character is present in both the head and the tail. let head_any = wc_segment.slice_to(asr_idx + 1); let any_tail = wc.slice_from(asr_idx); - assert!(head_any.chars().last().unwrap() == ANY_STRING_RECURSIVE); + assert!(head_any.chars().next_back().unwrap() == ANY_STRING_RECURSIVE); assert!(any_tail.chars().next().unwrap() == ANY_STRING_RECURSIVE); dir.rewind();