Skip to content

Commit 3a1e302

Browse files
committed
perf: avoid Vec alloc and double norm_case in pet-hatch hot path (PR #460)
1 parent beef4e5 commit 3a1e302

1 file changed

Lines changed: 15 additions & 6 deletions

File tree

crates/pet-hatch/src/lib.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -337,18 +337,27 @@ fn platform_default_data_dir(environment: &dyn Environment) -> Option<PathBuf> {
337337
fn match_default_storage_layout(prefix: &Path, storage: &Path) -> Option<String> {
338338
let normalized = norm_case(prefix);
339339
let rel = normalized.strip_prefix(storage).ok()?;
340-
let parts: Vec<_> = rel.iter().collect();
341-
if parts.len() == 3 {
342-
Some(parts[2].to_string_lossy().to_string())
343-
} else {
344-
None
340+
// Iterate components directly to avoid a per-call Vec allocation on the
341+
// identification hot path. We need exactly three components.
342+
let mut iter = rel.iter();
343+
let _project_name = iter.next()?;
344+
let _project_id = iter.next()?;
345+
let venv_name = iter.next()?;
346+
if iter.next().is_some() {
347+
return None;
345348
}
349+
Some(venv_name.to_string_lossy().to_string())
346350
}
347351

348352
/// True iff `prefix`'s parent equals `dir` (case-insensitive on Windows).
353+
///
354+
/// `dir` is expected to be already normalized via `norm_case()` (entries
355+
/// cached in `resolve_project_virtual_dirs()` always are), so we only
356+
/// normalize `prefix.parent()` here — avoiding redundant `GetLongPathNameW`
357+
/// / case-folding work on Windows in the identification hot path.
349358
fn prefix_is_directly_under(prefix: &Path, dir: &Path) -> bool {
350359
match prefix.parent() {
351-
Some(parent) => norm_case(parent) == norm_case(dir),
360+
Some(parent) => norm_case(parent) == dir,
352361
None => false,
353362
}
354363
}

0 commit comments

Comments
 (0)