Memoize and avoid candidate creation calls (#8230)

Trivial thing I noticed recently that improves performance by 1% in the
cached case :)
This commit is contained in:
Charlie Marsh 2023-10-25 14:50:58 -07:00 committed by GitHub
parent 9792b1551b
commit ff9fb0da54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -9,6 +9,7 @@ use std::sync::RwLock;
use anyhow::Result; use anyhow::Result;
use anyhow::{anyhow, bail}; use anyhow::{anyhow, bail};
use globset::{Candidate, GlobSet};
use ignore::{WalkBuilder, WalkState}; use ignore::{WalkBuilder, WalkState};
use itertools::Itertools; use itertools::Itertools;
use log::debug; use log::debug;
@ -333,12 +334,18 @@ pub fn python_files_in_path(
let resolver = resolver.read().unwrap(); let resolver = resolver.read().unwrap();
let settings = resolver.resolve(path, pyproject_config); let settings = resolver.resolve(path, pyproject_config);
if let Some(file_name) = path.file_name() { 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); debug!("Ignored path via `exclude`: {:?}", path);
return WalkState::Skip; return WalkState::Skip;
} else if match_exclusion( } else if match_candidate_exclusion(
path, &file_path,
file_name, &file_basename,
&settings.file_resolver.extend_exclude, &settings.file_resolver.extend_exclude,
) { ) {
debug!("Ignored path via `extend-exclude`: {:?}", path); debug!("Ignored path via `extend-exclude`: {:?}", path);
@ -509,10 +516,20 @@ fn is_file_excluded(
for path in path.ancestors() { for path in path.ancestors() {
let settings = resolver.resolve(path, pyproject_strategy); let settings = resolver.resolve(path, pyproject_strategy);
if let Some(file_name) = path.file_name() { 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); debug!("Ignored path via `exclude`: {:?}", path);
return true; 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); debug!("Ignored path via `extend-exclude`: {:?}", path);
return true; return true;
} }
@ -533,11 +550,27 @@ fn is_file_excluded(
pub fn match_exclusion<P: AsRef<Path>, R: AsRef<Path>>( pub fn match_exclusion<P: AsRef<Path>, R: AsRef<Path>>(
file_path: P, file_path: P,
file_basename: R, file_basename: R,
exclusion: &globset::GlobSet, exclusion: &GlobSet,
) -> bool { ) -> bool {
if exclusion.is_empty() {
return false;
}
exclusion.is_match(file_path) || exclusion.is_match(file_basename) 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)] #[cfg(test)]
mod tests { mod tests {
use std::fs::{create_dir, File}; use std::fs::{create_dir, File};