Skip to content

pkg/paths: compare cleaned paths in FS.HasPrefix outside Windows - #2632

Open
twindebank wants to merge 1 commit into
encoredev:mainfrom
gradientlabs-ai:paths-hasprefix-no-rel
Open

twindebank wants to merge 1 commit into
encoredev:mainfrom
gradientlabs-ai:paths-hasprefix-no-rel

Conversation

@twindebank

@twindebank twindebank commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Problem

paths.FS.HasPrefix reports whether a path is a folder or inside it. It calls filepath.Rel and then filepath.IsLocal on the result. When the path is not inside the folder, filepath.Rel builds a ../.. path to return, so every miss allocates.

The parser asks this for every package against every service, through ServiceForPath and others. Nearly every answer is no. On an app with a few hundred services that is hundreds of thousands of allocating calls per parse.

Fix

Outside Windows, filepath.Rel compares the cleaned paths byte by byte. So for two absolute paths, a prefix check on the cleaned paths gives the same answer and allocates nothing. Windows, where filepath.Rel ignores case, and any relative path still go through filepath.Rel.

Impact

Finding the service for a path by calling HasPrefix against each of 300 services, on main (go test -bench, five runs each):

Time per lookup Allocations
Before ~60 µs 299
After ~17 µs 0

On a large app (a few hundred services, ~1,400 packages) the parse went from 5.7 s to 4.1 s.

Tests

TestFSHasPrefix checks the new check against filepath.Rel for every pair from a set of awkward paths. They include the root, trailing and doubled slashes, .., different case, relative paths, and a shared prefix that is not a parent (/a/bc against /a/b). It also checks with testing.AllocsPerRun that a match and a miss allocate nothing.

  • On main it fails: a miss allocates once per call.
  • With the fix it passes (go test -short -tags=dev_build ./pkg/paths).

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

HasPrefix called filepath.Rel, which builds a "../.." path whenever the
path is not under the folder. The parser checks every package against
every service, so most calls are misses and each one allocated. Outside
Windows, filepath.Rel compares bytes, so a prefix check on the cleaned
paths gives the same answer without allocating.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant