diff options
author | Joe Tsai <joetsai@digital-static.net> | 2022-09-22 16:54:19 -0700 |
---|---|---|
committer | Gopher Robot <gobot@golang.org> | 2022-09-23 04:34:52 +0000 |
commit | 2551324cd01b295915c10c6d3d06625676401610 (patch) | |
tree | 19c7efe7b981bfaa81d0180cdd94bb1196b03bf5 /src/path | |
parent | c2ede92a0d461cca8ab5fba8840e15670710fbd9 (diff) | |
download | go-2551324cd01b295915c10c6d3d06625676401610.tar.gz go-2551324cd01b295915c10c6d3d06625676401610.zip |
path/filepath: optimize isReservedName
A linear search through a list of 22 strings takes ~80ns.
A quick check for 3-4 byte strings reduces this check to 2ns
for a vast majority of inputs.
In the event of a name match, the new logic is either just
as fast (for "CON") or 10x faster (for "LPT9").
Change-Id: I412fa73beebd7c81dc95f9ed12c35ca1d5d6baf0
Reviewed-on: https://go-review.googlesource.com/c/go/+/433175
Reviewed-by: Damien Neil <dneil@google.com>
Run-TryBot: Joseph Tsai <joetsai@digital-static.net>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Joseph Tsai <joetsai@digital-static.net>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Diffstat (limited to 'src/path')
-rw-r--r-- | src/path/filepath/path_windows.go | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/src/path/filepath/path_windows.go b/src/path/filepath/path_windows.go index b4d8ac3301..80998decc6 100644 --- a/src/path/filepath/path_windows.go +++ b/src/path/filepath/path_windows.go @@ -13,24 +13,24 @@ func isSlash(c uint8) bool { return c == '\\' || c == '/' } -// reservedNames lists reserved Windows names. Search for PRN in -// https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file -// for details. -var reservedNames = []string{ - "CON", "PRN", "AUX", "NUL", - "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", - "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", -} - // isReservedName returns true, if path is Windows reserved name. // See reservedNames for the full list. func isReservedName(path string) bool { - if len(path) == 0 { - return false + toUpper := func(c byte) byte { + if 'a' <= c && c <= 'z' { + return c - ('a' - 'A') + } + return c } - for _, reserved := range reservedNames { - if strings.EqualFold(path, reserved) { - return true + + // For details, search for PRN in + // https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file. + if 3 <= len(path) && len(path) <= 4 { + switch string([]byte{toUpper(path[0]), toUpper(path[1]), toUpper(path[2])}) { + case "CON", "PRN", "AUX", "NUL": + return len(path) == 3 + case "COM", "LPT": + return len(path) == 4 && '1' <= path[3] && path[3] <= '9' } } return false |