mirror of
https://github.com/nushell/nushell.git
synced 2025-08-17 09:01:10 +02:00
perf: reorder cell-path member accesses to avoid clones (#15682)
Co-authored-by: Bahex <17417311+Bahex@users.noreply.github.com> Co-authored-by: Piepmatz <git+github@cptpiepmatz.de>
This commit is contained in:
@ -21,6 +21,7 @@ nu-glob = { path = "../nu-glob", version = "0.105.2" }
|
||||
nu-path = { path = "../nu-path", version = "0.105.2" }
|
||||
nu-system = { path = "../nu-system", version = "0.105.2" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.105.2", default-features = false }
|
||||
nu-experimental = { path = "../nu-experimental", version = "0.105.2" }
|
||||
|
||||
brotli = { workspace = true, optional = true }
|
||||
bytes = { workspace = true }
|
||||
|
@ -1111,7 +1111,55 @@ impl Value {
|
||||
let mut store: Value = Value::test_nothing();
|
||||
let mut current: MultiLife<'out, '_, Value> = MultiLife::Out(self);
|
||||
|
||||
for member in cell_path {
|
||||
let reorder_cell_paths = nu_experimental::REORDER_CELL_PATHS.get();
|
||||
|
||||
let mut members: Vec<_> = if reorder_cell_paths {
|
||||
cell_path.iter().map(Some).collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let mut members = members.as_mut_slice();
|
||||
let mut cell_path = cell_path;
|
||||
|
||||
loop {
|
||||
let member = if reorder_cell_paths {
|
||||
// Skip any None values at the start.
|
||||
while let Some(None) = members.first() {
|
||||
members = &mut members[1..];
|
||||
}
|
||||
|
||||
if members.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
// Reorder cell-path member access by prioritizing Int members to avoid cloning unless
|
||||
// necessary
|
||||
let member = if let Value::List { .. } = &*current {
|
||||
// If the value is a list, try to find an Int member
|
||||
members
|
||||
.iter_mut()
|
||||
.find(|x| matches!(x, Some(PathMember::Int { .. })))
|
||||
// And take it from the list of members
|
||||
.and_then(Option::take)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let Some(member) = member.or_else(|| members.first_mut().and_then(Option::take))
|
||||
else {
|
||||
break;
|
||||
};
|
||||
member
|
||||
} else {
|
||||
match cell_path {
|
||||
[first, rest @ ..] => {
|
||||
cell_path = rest;
|
||||
first
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
};
|
||||
|
||||
current = match current {
|
||||
MultiLife::Out(current) => match get_value_member(current, member)? {
|
||||
ControlFlow::Break(span) => return Ok(Cow::Owned(Value::nothing(span))),
|
||||
|
Reference in New Issue
Block a user