Improve Python uninstall perf by removing unnecessary call to installations.find_all() (#14180)
#13954 introduced an unnecessary slow-down to Python uninstall by calling `installations.find_all()` to discover remaining installations after an uninstall. Instead, we can filter all initial installations against those in `uninstalled`. As part of this change, I've updated `uninstalled` from a `Vec` to an `IndexSet` in order to do efficient lookups in the filter. This required a change I call out below to how we were retrieving them for messaging.
This commit is contained in:
@@ -200,13 +200,13 @@ async fn do_uninstall(
|
||||
});
|
||||
}
|
||||
|
||||
let mut uninstalled = vec![];
|
||||
let mut uninstalled = IndexSet::<PythonInstallationKey>::default();
|
||||
let mut errors = vec![];
|
||||
while let Some((key, result)) = tasks.next().await {
|
||||
if let Err(err) = result {
|
||||
errors.push((key.clone(), anyhow::Error::new(err)));
|
||||
} else {
|
||||
uninstalled.push(key.clone());
|
||||
uninstalled.insert(key.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,14 +223,15 @@ async fn do_uninstall(
|
||||
// Read all existing managed installations and find the highest installed patch
|
||||
// for each installed minor version. Ensure the minor version link directory
|
||||
// is still valid.
|
||||
let uninstalled_minor_versions = &uninstalled.iter().fold(
|
||||
IndexSet::<&PythonInstallationMinorVersionKey>::default(),
|
||||
|mut minor_versions, key| {
|
||||
minor_versions.insert(PythonInstallationMinorVersionKey::ref_cast(key));
|
||||
minor_versions
|
||||
},
|
||||
);
|
||||
let remaining_installations: Vec<_> = installations.find_all()?.collect();
|
||||
let uninstalled_minor_versions: IndexSet<_> = uninstalled
|
||||
.iter()
|
||||
.map(PythonInstallationMinorVersionKey::ref_cast)
|
||||
.collect();
|
||||
let remaining_installations: Vec<_> = installed_installations
|
||||
.into_iter()
|
||||
.filter(|installation| !uninstalled.contains(installation.key()))
|
||||
.collect();
|
||||
|
||||
let remaining_minor_versions =
|
||||
PythonInstallationMinorVersionKey::highest_installations_by_minor_version_key(
|
||||
remaining_installations.iter(),
|
||||
@@ -278,28 +279,27 @@ async fn do_uninstall(
|
||||
}
|
||||
|
||||
// Report on any uninstalled installations.
|
||||
if !uninstalled.is_empty() {
|
||||
if let [uninstalled] = uninstalled.as_slice() {
|
||||
if let Some(first_uninstalled) = uninstalled.first() {
|
||||
if uninstalled.len() == 1 {
|
||||
// Ex) "Uninstalled Python 3.9.7 in 1.68s"
|
||||
writeln!(
|
||||
printer.stderr(),
|
||||
"{}",
|
||||
format!(
|
||||
"Uninstalled {} {}",
|
||||
format!("Python {}", uninstalled.version()).bold(),
|
||||
format!("Python {}", first_uninstalled.version()).bold(),
|
||||
format!("in {}", elapsed(start.elapsed())).dimmed()
|
||||
)
|
||||
.dimmed()
|
||||
)?;
|
||||
} else {
|
||||
// Ex) "Uninstalled 2 versions in 1.68s"
|
||||
let s = if uninstalled.len() == 1 { "" } else { "s" };
|
||||
writeln!(
|
||||
printer.stderr(),
|
||||
"{}",
|
||||
format!(
|
||||
"Uninstalled {} {}",
|
||||
format!("{} version{s}", uninstalled.len()).bold(),
|
||||
format!("{} versions", uninstalled.len()).bold(),
|
||||
format!("in {}", elapsed(start.elapsed())).dimmed()
|
||||
)
|
||||
.dimmed()
|
||||
|
||||
Reference in New Issue
Block a user