Clear TestDrive with .NET IO instead of per-item Remove-Item#2917
Open
nohwnd wants to merge 1 commit into
Open
Clear TestDrive with .NET IO instead of per-item Remove-Item#2917nohwnd wants to merge 1 commit into
nohwnd wants to merge 1 commit into
Conversation
Clear-TestDrive ran Remove-Item -Path -Force -Recurse for every new root item after each block. Remove-Item costs ~470us per item where IO.Directory/IO.File Delete costs ~85us, and -Path treats the path as a wildcard pattern, so a file named like 'file[1].txt' was never deleted and leaked across block teardowns. The .NET calls treat the path literally, delete reparse points without following them into their target (same as Remove-TestDrive already does for the whole drive since 2021), and anything that throws (read-only files on Windows, locked files) falls back to Remove-Item -LiteralPath -Force -ErrorAction Ignore, keeping the old semantics for those. Also replaced a Join-Path with plain string interpolation in New-RandomTempRegistry, registry provider paths always use backslash. 🤖
This was referenced Jul 19, 2026
fflaten
reviewed
Jul 19, 2026
Comment on lines
+98
to
+99
| # registry provider paths always use backslash; plain interpolation avoids a per-call cmdlet invocation | ||
| $Path = "$tempPath\$([IO.Path]::GetRandomFileName().Substring(0, 4))" |
Collaborator
There was a problem hiding this comment.
Not really a hot path, but sure 👍
Member
Author
There was a problem hiding this comment.
got some free fable tokens, told it to optimize (especially the hot path), looks like most of the optimizations are microscopic.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Clear-TestDriveranRemove-Item -Path $item -Force -Recurse -ErrorAction Ignorefor every new root item after each block. Two problems with that:Remove-Itemcosts ~470us per item where[IO.Directory]::Delete/[IO.File]::Deletecost ~85us. On a TestDrive-heavy suite the cleanup was the single hottest line in the profile.-Pathtreats the path as a wildcard pattern. A file named likefile[1].txtnever matched its own name, was never deleted, and leaked across block teardowns. The reverse is also possible, a name with*in it could over-delete. The .NET calls treat the path literally, so this is also a small bug fix.Symlink semantics stay the same: recursive
Directory.Deleteremoves reparse points without following them into their target, which is whatRemove-TestDrivehas already been doing for the whole drive with the exact same call since 2021. I verified this empirically on macOS with dir symlinks, file symlinks, dangling links, the PowerShell/PowerShell#621 problematic link set, and a symlink cycle, the linked target content survives in all cases. Anything that throws (read-only files on Windows, locked files) falls back toRemove-Item -LiteralPath -Force -Recurse -ErrorAction Ignore, keeping the old behavior for those, just slower on that rare path.A ride-along in
New-RandomTempRegistry:Join-Pathreplaced with plain string interpolation, registry provider paths always use backslash and the base key has no trailing separator, so the result is identical and it skips a cmdlet invocation per new registry key.One heads-up: the symlink tests in
TestDrive.Tests.ps1are entirely commented out (they needed admin on Windows), so nothing in CI exercises symlink cleanup today. Might be worth re-enabling them at least on Linux/macOS runners in a separate PR.Verification: full suite green on macOS (inline and dot-sourced build),
TestDrive.Tests.ps1including the Clear-TestDrive #2657 regression suite andPester.TestDrive.ts.ps1pass.Related perf PRs: #2914, #2915, #2916, #2918. Measured together they cut ~21% from four representative workloads (inline build, macOS).
🤖