From 2fd51355c33bb4bb9ab2bdca07e2e0e7e2b1993b Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Fri, 22 Nov 2024 16:31:03 -0600 Subject: [PATCH] Speed up wcscasecmp by approximately 30-40% Moving the "make empty ToLowercase iterator" logic to within the `unwrap_or_else()` instead of always generating it brings most of the speedup; unrolling the recursive call brings in the rest. --- src/fallback.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/fallback.rs b/src/fallback.rs index 1c560a3a3..95cdea0be 100644 --- a/src/fallback.rs +++ b/src/fallback.rs @@ -126,6 +126,7 @@ pub fn fish_mkstemp_cloexec(name_template: CString) -> Result<(File, CString), E } } +/// Compare two wide strings in a case-insensitive fashion pub fn wcscasecmp(lhs: &wstr, rhs: &wstr) -> cmp::Ordering { use std::char::ToLowercase; use widestring::utfstr::CharsUtf32; @@ -149,18 +150,20 @@ pub fn wcscasecmp(lhs: &wstr, rhs: &wstr) -> cmp::Ordering { } self.current = self.chars.next()?.to_lowercase(); - self.next() + self.current.next() } } impl<'a> ToLowerBuffer<'a> { pub fn from(w: &'a wstr) -> Self { - let mut empty = 'a'.to_lowercase(); - let _ = empty.next(); - debug_assert!(empty.next().is_none()); let mut chars = w.chars(); Self { - current: chars.next().map(|c| c.to_lowercase()).unwrap_or(empty), + current: chars.next().map(|c| c.to_lowercase()).unwrap_or_else(|| { + let mut empty = 'a'.to_lowercase(); + let _ = empty.next(); + debug_assert!(empty.next().is_none()); + empty + }), chars, } }