Avoid unnecessary allocations by caching the sorting factors

This commit is contained in:
sxyazi 2024-02-12 19:25:44 +08:00
parent b44452dbd9
commit 8a9b7279f8
No known key found for this signature in database
4 changed files with 33 additions and 30 deletions

View file

@ -5,7 +5,7 @@ use yazi_shared::event::Cmd;
use super::Key; use super::Key;
#[derive(Debug, Deserialize)] #[derive(Debug, Default, Deserialize)]
pub struct Control { pub struct Control {
pub on: Vec<Key>, pub on: Vec<Key>,
#[serde(deserialize_with = "super::exec_deserialize")] #[serde(deserialize_with = "super::exec_deserialize")]
@ -68,6 +68,10 @@ impl Deref for ControlCow {
} }
} }
impl Default for ControlCow {
fn default() -> Self { Self::Owned(Control::default()) }
}
impl ControlCow { impl ControlCow {
pub fn into_seq(self) -> VecDeque<Cmd> { pub fn into_seq(self) -> VecDeque<Cmd> {
match self { match self {

View file

@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
use validator::Validate; use validator::Validate;
use super::SortBy; use super::SortBy;
use crate::{validation::check_validation, MERGED_YAZI}; use crate::MERGED_YAZI;
#[derive(Debug, Deserialize, Serialize, Validate)] #[derive(Debug, Deserialize, Serialize, Validate)]
pub struct Which { pub struct Which {
@ -19,9 +19,6 @@ impl Default for Which {
which: Which, which: Which,
} }
let which = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().which; toml::from_str::<Outer>(&MERGED_YAZI).unwrap().which
check_validation(which.validate());
which
} }
} }

View file

@ -12,9 +12,9 @@ pub struct FilesSorter {
} }
impl FilesSorter { impl FilesSorter {
pub(super) fn sort(&self, items: &mut Vec<File>, sizes: &BTreeMap<Url, u64>) -> bool { pub(super) fn sort(&self, items: &mut Vec<File>, sizes: &BTreeMap<Url, u64>) {
if items.is_empty() { if items.is_empty() {
return false; return;
} }
let by_alphabetical = |a: &File, b: &File| { let by_alphabetical = |a: &File, b: &File| {
@ -30,7 +30,7 @@ impl FilesSorter {
}; };
match self.by { match self.by {
SortBy::None => return false, SortBy::None => {}
SortBy::Modified => items.sort_unstable_by(|a, b| { SortBy::Modified => items.sort_unstable_by(|a, b| {
let ord = self.cmp(a.modified, b.modified, self.promote(a, b)); let ord = self.cmp(a.modified, b.modified, self.promote(a, b));
if ord == Ordering::Equal { by_alphabetical(a, b) } else { ord } if ord == Ordering::Equal { by_alphabetical(a, b) } else { ord }
@ -60,7 +60,6 @@ impl FilesSorter {
if ord == Ordering::Equal { by_alphabetical(a, b) } else { ord } if ord == Ordering::Equal { by_alphabetical(a, b) } else { ord }
}), }),
} }
true
} }
fn sort_naturally(&self, items: &mut Vec<File>) { fn sort_naturally(&self, items: &mut Vec<File>) {

View file

@ -1,3 +1,5 @@
use std::{borrow::Cow, mem};
use yazi_config::{keymap::ControlCow, which::SortBy}; use yazi_config::{keymap::ControlCow, which::SortBy};
use yazi_shared::natsort; use yazi_shared::natsort;
@ -9,30 +11,31 @@ pub struct WhichSorter {
} }
impl WhichSorter { impl WhichSorter {
pub(super) fn sort(&self, items: &mut Vec<ControlCow>) -> bool { pub(super) fn sort(&self, items: &mut Vec<ControlCow>) {
if items.is_empty() { if self.by == SortBy::None || items.is_empty() {
return false; return;
} }
let by_alphabetical = |a: &str, b: &str| { let mut indices = Vec::with_capacity(items.len());
let ordering = natsort(a.as_bytes(), b.as_bytes(), !self.sensitive); let mut entities = Vec::with_capacity(items.len());
for (i, ctrl) in items.iter().enumerate() {
indices.push(i);
entities.push(match self.by {
SortBy::None => unreachable!(),
SortBy::Key => Cow::Owned(ctrl.on()),
SortBy::Desc => ctrl.desc_or_exec(),
});
}
indices.sort_unstable_by(|&a, &b| {
let ordering = natsort(entities[a].as_bytes(), entities[b].as_bytes(), !self.sensitive);
if self.reverse { ordering.reverse() } else { ordering } if self.reverse { ordering.reverse() } else { ordering }
}; });
match self.by { let mut new = Vec::with_capacity(indices.len());
SortBy::None => return false, for i in indices {
SortBy::Key => items.sort_unstable_by(|a, b| { new.push(mem::take(&mut items[i]));
let a = a.on.iter().map(|c| c.to_string()).collect::<String>();
let b = b.on.iter().map(|c| c.to_string()).collect::<String>();
by_alphabetical(&a, &b)
}),
SortBy::Desc => items.sort_unstable_by(|a, b| {
// what if description isn't present (need to check if it's mandatory or not)
// in case if it is not present, should I just panic ?
by_alphabetical(a.desc.as_ref().unwrap(), b.desc.as_ref().unwrap())
}),
} }
*items = new;
true
} }
} }