Skip to content

Commit

Permalink
perf: eliminate all memory reallocations during sorting (#1846)
Browse files Browse the repository at this point in the history
  • Loading branch information
sxyazi authored Oct 28, 2024
1 parent ef1a31a commit 4dd24f7
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 53 deletions.
82 changes: 35 additions & 47 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion yazi-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
31 changes: 27 additions & 4 deletions yazi-fs/src/sorter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
)
}
};

Expand All @@ -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),
)
};
Expand Down Expand Up @@ -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 }
Expand Down
2 changes: 1 addition & 1 deletion yazi-scheduler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

0 comments on commit 4dd24f7

Please sign in to comment.