From 381811b4a6b413b803f403ea776475ffc5eb3f95 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 9 Jan 2024 08:33:22 -0500 Subject: [PATCH] Skip extra settings resolution when namespace packages are empty (#9446) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Saves 2% on Airflow: ```shell ❯ hyperfine --warmup 20 -i "./target/release/main format ../airflow" "./target/release/ruff format ../airflow" Benchmark 1: ./target/release/main format ../airflow Time (mean ± σ): 72.7 ms ± 0.4 ms [User: 48.7 ms, System: 75.5 ms] Range (min … max): 72.0 ms … 73.7 ms 40 runs Benchmark 2: ./target/release/ruff format ../airflow Time (mean ± σ): 71.4 ms ± 0.6 ms [User: 46.2 ms, System: 76.2 ms] Range (min … max): 70.3 ms … 73.8 ms 41 runs Summary './target/release/ruff format ../airflow' ran 1.02 ± 0.01 times faster than './target/release/main format ../airflow' ``` --- crates/ruff_workspace/src/resolver.rs | 34 +++++++++++++++++++-------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/crates/ruff_workspace/src/resolver.rs b/crates/ruff_workspace/src/resolver.rs index ac1f94294a9ff..2c6108f828974 100644 --- a/crates/ruff_workspace/src/resolver.rs +++ b/crates/ruff_workspace/src/resolver.rs @@ -139,21 +139,35 @@ impl Resolver { } } + // Determine whether any of the settings require namespace packages. If not, we can save + // a lookup for every file. + let has_namespace_packages = self + .settings + .values() + .any(|settings| !settings.linter.namespace_packages.is_empty()); + // Search for the package root for each file. let mut package_roots: FxHashMap<&Path, Option<&Path>> = FxHashMap::default(); for file in files { - let namespace_packages = &self - .resolve(file, pyproject_config) - .linter - .namespace_packages; if let Some(package) = file.parent() { - if package_roots.contains_key(package) { - continue; + match package_roots.entry(package) { + std::collections::hash_map::Entry::Occupied(_) => continue, + std::collections::hash_map::Entry::Vacant(entry) => { + let namespace_packages = if has_namespace_packages { + self.resolve(file, pyproject_config) + .linter + .namespace_packages + .as_slice() + } else { + &[] + }; + entry.insert(detect_package_root_with_cache( + package, + namespace_packages, + &mut package_cache, + )); + } } - package_roots.insert( - package, - detect_package_root_with_cache(package, namespace_packages, &mut package_cache), - ); } }