From b23756778663db031a04320535069591c93bad59 Mon Sep 17 00:00:00 2001 From: reuben olinsky Date: Sat, 25 Jan 2025 23:11:03 -0800 Subject: [PATCH] perf: simplify export enumeration (#363) --- brush-core/src/commands.rs | 11 +++-------- brush-core/src/env.rs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/brush-core/src/commands.rs b/brush-core/src/commands.rs index b3464bf..37fa080 100644 --- a/brush-core/src/commands.rs +++ b/brush-core/src/commands.rs @@ -212,9 +212,7 @@ pub(crate) fn compose_std_command>( cmd.arg0(argv0); // Pass through args. - for arg in args { - cmd.arg(arg); - } + cmd.args(args); // Use the shell's current working dir. cmd.current_dir(shell.working_dir.as_path()); @@ -224,11 +222,8 @@ pub(crate) fn compose_std_command>( // Add in exported variables. if !empty_env { - for (name, var) in shell.env.iter() { - if var.is_exported() { - let value_as_str = var.value().to_cow_str(shell); - cmd.env(name, value_as_str.as_ref()); - } + for (k, v) in shell.env.iter_exported() { + cmd.env(k.as_str(), v.value().to_cow_str(shell).as_ref()); } } diff --git a/brush-core/src/env.rs b/brush-core/src/env.rs index 2dd2f44..db5609c 100644 --- a/brush-core/src/env.rs +++ b/brush-core/src/env.rs @@ -83,6 +83,25 @@ impl ShellEnvironment { // Iterators/Getters // + /// Returns an iterator over all exported variables defined in the variable. + pub fn iter_exported(&self) -> impl Iterator { + // We won't actually need to store all entries, but we expect it should be + // within the same order. + let mut visible_vars: HashMap<&String, &ShellVariable> = + HashMap::with_capacity(self.entry_count); + + for (_, var_map) in self.scopes.iter().rev() { + for (name, var) in var_map.iter().filter(|(_, v)| v.is_exported()) { + // Only insert the variable if it hasn't been seen yet. + if let hash_map::Entry::Vacant(entry) = visible_vars.entry(name) { + entry.insert(var); + } + } + } + + visible_vars.into_iter() + } + /// Returns an iterator over all the variables defined in the environment. pub fn iter(&self) -> impl Iterator { self.iter_using_policy(EnvironmentLookup::Anywhere)