From ff9fb0da54c0ecd3a555948922bcab46ee770954 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 25 Oct 2023 14:50:58 -0700 Subject: [PATCH] Memoize and avoid candidate creation calls (#8230) Trivial thing I noticed recently that improves performance by 1% in the cached case :) --- crates/ruff_workspace/src/resolver.rs | 47 +++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/crates/ruff_workspace/src/resolver.rs b/crates/ruff_workspace/src/resolver.rs index aeca97709b0c6..6bf5671a3ca59 100644 --- a/crates/ruff_workspace/src/resolver.rs +++ b/crates/ruff_workspace/src/resolver.rs @@ -9,6 +9,7 @@ use std::sync::RwLock; use anyhow::Result; use anyhow::{anyhow, bail}; +use globset::{Candidate, GlobSet}; use ignore::{WalkBuilder, WalkState}; use itertools::Itertools; use log::debug; @@ -333,12 +334,18 @@ pub fn python_files_in_path( let resolver = resolver.read().unwrap(); let settings = resolver.resolve(path, pyproject_config); if let Some(file_name) = path.file_name() { - if match_exclusion(path, file_name, &settings.file_resolver.exclude) { + let file_path = Candidate::new(path); + let file_basename = Candidate::new(file_name); + if match_candidate_exclusion( + &file_path, + &file_basename, + &settings.file_resolver.exclude, + ) { debug!("Ignored path via `exclude`: {:?}", path); return WalkState::Skip; - } else if match_exclusion( - path, - file_name, + } else if match_candidate_exclusion( + &file_path, + &file_basename, &settings.file_resolver.extend_exclude, ) { debug!("Ignored path via `extend-exclude`: {:?}", path); @@ -509,10 +516,20 @@ fn is_file_excluded( for path in path.ancestors() { let settings = resolver.resolve(path, pyproject_strategy); if let Some(file_name) = path.file_name() { - if match_exclusion(path, file_name, &settings.file_resolver.exclude) { + let file_path = Candidate::new(path); + let file_basename = Candidate::new(file_name); + if match_candidate_exclusion( + &file_path, + &file_basename, + &settings.file_resolver.exclude, + ) { debug!("Ignored path via `exclude`: {:?}", path); return true; - } else if match_exclusion(path, file_name, &settings.file_resolver.extend_exclude) { + } else if match_candidate_exclusion( + &file_path, + &file_basename, + &settings.file_resolver.extend_exclude, + ) { debug!("Ignored path via `extend-exclude`: {:?}", path); return true; } @@ -533,11 +550,27 @@ fn is_file_excluded( pub fn match_exclusion, R: AsRef>( file_path: P, file_basename: R, - exclusion: &globset::GlobSet, + exclusion: &GlobSet, ) -> bool { + if exclusion.is_empty() { + return false; + } exclusion.is_match(file_path) || exclusion.is_match(file_basename) } +/// Return `true` if the given candidates should be ignored based on the exclusion +/// criteria. +pub fn match_candidate_exclusion( + file_path: &Candidate, + file_basename: &Candidate, + exclusion: &GlobSet, +) -> bool { + if exclusion.is_empty() { + return false; + } + exclusion.is_match_candidate(file_path) || exclusion.is_match_candidate(file_basename) +} + #[cfg(test)] mod tests { use std::fs::{create_dir, File};