From 4dd24f779ca4dd50f39f49d6d53e5d83c4385215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Mon, 28 Oct 2024 15:36:27 +0800 Subject: [PATCH] perf: eliminate all memory reallocations during sorting (#1846) --- Cargo.lock | 82 +++++++++++++++++---------------------- yazi-core/Cargo.toml | 2 +- yazi-fs/src/sorter.rs | 31 +++++++++++++-- yazi-scheduler/Cargo.toml | 2 +- 4 files changed, 64 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c33b9f4d..211aab3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,9 +74,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -89,36 +89,36 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -462,9 +462,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "compact_str" @@ -561,7 +561,7 @@ dependencies = [ "filedescriptor", "futures-core", "libc", - "mio 1.0.2", + "mio", "parking_lot", "rustix", "signal-hook", @@ -773,9 +773,9 @@ dependencies = [ [[package]] name = "fdeflate" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab" +checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb" dependencies = [ "simd-adler32", ] @@ -1410,18 +1410,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", -] - [[package]] name = "mio" version = "1.0.2" @@ -1455,9 +1443,9 @@ dependencies = [ [[package]] name = "mlua-sys" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe026d6bd1583a9cf9080e189030ddaea7e6f5f0deb366a8e26f8a26c4135b8" +checksum = "e9eebac25c35a13285456c88ee2fde93d9aee8bcfdaf03f9d6d12be3391351ec" dependencies = [ "cc", "cfg-if", @@ -1504,10 +1492,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] -name = "notify-fork" -version = "6.1.1" +name = "notify" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f610737468f7a95610d2b320b5d5e246b3cd1c3603782680c0f454ac5825b64b" +checksum = "c533b4c39709f9ba5005d8002048266593c1cfaf3c5f0739d5b8ab0c6c504009" dependencies = [ "bitflags 2.6.0", "filetime", @@ -1516,17 +1504,17 @@ dependencies = [ "kqueue", "libc", "log", - "mio 0.8.11", - "notify-types-fork", + "mio", + "notify-types", "walkdir", "windows-sys 0.52.0", ] [[package]] -name = "notify-types-fork" +name = "notify-types" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc01866a421a4ce1eddc764da8a95b30b82aa0d9d7f33508265c196d4863b18" +checksum = "7393c226621f817964ffb3dc5704f9509e107a8b024b489cc2c1b217378785df" dependencies = [ "instant", ] @@ -1741,9 +1729,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -2072,9 +2060,9 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" dependencies = [ "bitflags 2.6.0", "errno", @@ -2199,7 +2187,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", - "mio 1.0.2", + "mio", "signal-hook", ] @@ -2481,7 +2469,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.2", + "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -2631,9 +2619,9 @@ dependencies = [ [[package]] name = "trash" -version = "5.1.1" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33caf2a9be1812a263a4bfce74d2de225fcde12ee7b77001361abd2b34ffdcc4" +checksum = "defe1fdd4232e407b312377885a2c5396764972bddad87baf304753374a1bfc8" dependencies = [ "chrono", "libc", @@ -3280,7 +3268,7 @@ dependencies = [ "dirs", "futures", "libc", - "notify-fork", + "notify", "parking_lot", "ratatui", "scopeguard", diff --git a/yazi-core/Cargo.toml b/yazi-core/Cargo.toml index f4744c63..fc7bb804 100644 --- a/yazi-core/Cargo.toml +++ b/yazi-core/Cargo.toml @@ -27,7 +27,7 @@ bitflags = { workspace = true } crossterm = { workspace = true } dirs = { workspace = true } futures = { workspace = true } -notify = { package = "notify-fork", version = "6.1.1", default-features = false, features = [ "macos_fsevent" ] } +notify = { version = "7.0.0", default-features = false, features = [ "macos_fsevent" ] } parking_lot = { workspace = true } ratatui = { workspace = true } scopeguard = { workspace = true } diff --git a/yazi-fs/src/sorter.rs b/yazi-fs/src/sorter.rs index fee270bc..86315bcd 100644 --- a/yazi-fs/src/sorter.rs +++ b/yazi-fs/src/sorter.rs @@ -22,7 +22,11 @@ impl FilesSorter { if self.sensitive { self.cmp(a.name(), b.name(), self.promote(a, b)) } else { - self.cmp(a.name().to_ascii_uppercase(), b.name().to_ascii_uppercase(), self.promote(a, b)) + self.cmp_insensitive( + a.name().as_encoded_bytes(), + b.name().as_encoded_bytes(), + self.promote(a, b), + ) } }; @@ -40,9 +44,9 @@ impl FilesSorter { let ord = if self.sensitive { self.cmp(a.url.extension(), b.url.extension(), self.promote(a, b)) } else { - self.cmp( - a.url.extension().map(|s| s.to_ascii_lowercase()), - b.url.extension().map(|s| s.to_ascii_lowercase()), + self.cmp_insensitive( + a.url.extension().map_or(&[], |s| s.as_encoded_bytes()), + b.url.extension().map_or(&[], |s| s.as_encoded_bytes()), self.promote(a, b), ) }; @@ -99,6 +103,25 @@ impl FilesSorter { } } + #[inline(always)] + fn cmp_insensitive(&self, a: &[u8], b: &[u8], promote: Ordering) -> Ordering { + if promote != Ordering::Equal { + return promote; + } + + let l = a.len().min(b.len()); + let (lhs, rhs) = if self.reverse { (&b[..l], &a[..l]) } else { (&a[..l], &b[..l]) }; + + for i in 0..l { + match lhs[i].to_ascii_lowercase().cmp(&rhs[i].to_ascii_lowercase()) { + Ordering::Equal => (), + not_eq => return not_eq, + } + } + + if self.reverse { b.len().cmp(&a.len()) } else { a.len().cmp(&b.len()) } + } + #[inline(always)] fn promote(&self, a: &File, b: &File) -> Ordering { if self.dir_first { b.is_dir().cmp(&a.is_dir()) } else { Ordering::Equal } diff --git a/yazi-scheduler/Cargo.toml b/yazi-scheduler/Cargo.toml index 288add37..330b89bd 100644 --- a/yazi-scheduler/Cargo.toml +++ b/yazi-scheduler/Cargo.toml @@ -29,4 +29,4 @@ tracing = { workspace = true } libc = { workspace = true } [target.'cfg(not(target_os = "android"))'.dependencies] -trash = "5.1.1" +trash = "5.2.0"