Repository navigation
pkg/paths: compare cleaned paths in FS.HasPrefix outside Windows - #2632
Open
twindebank wants to merge 1 commit into
Open
twindebank wants to merge 1 commit into
twindebank wants to merge 1 commit into
Conversation
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
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.
Problem
paths.FS.HasPrefixreports whether a path is a folder or inside it. It callsfilepath.Reland thenfilepath.IsLocalon the result. When the path is not inside the folder,filepath.Relbuilds a../..path to return, so every miss allocates.The parser asks this for every package against every service, through
ServiceForPathand 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.Relcompares 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, wherefilepath.Relignores case, and any relative path still go throughfilepath.Rel.Impact
Finding the service for a path by calling
HasPrefixagainst each of 300 services, onmain(go test -bench, five runs each):On a large app (a few hundred services, ~1,400 packages) the parse went from 5.7 s to 4.1 s.
Tests
TestFSHasPrefixchecks the new check againstfilepath.Relfor 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/bcagainst/a/b). It also checks withtesting.AllocsPerRunthat a match and a miss allocate nothing.mainit fails: a miss allocates once per call.go test -short -tags=dev_build ./pkg/paths).Need help on this PR? Tag
@codesmith-botwith what you need.