Skip to content

Commit cbb8e8e

Browse files
committed
internal/span: optimise URI.Filename to avoid allocation
This change adds a fast-path check for the common case: "file:", lowercase, followed by a simple POSIX absolute file name without special characters. This function used to account for 1% of CPU on the DidChange benchmark (and I'm sure I've seen higher fractions on other tests--but perhaps that was before the clone optimizations?). It was tested by adding an assertion that it agrees with the slow path and running all our tests. Change-Id: I15492b8a317715468870b00041bf8f6b0bb53bb2 Reviewed-on: https://go-review.googlesource.com/c/tools/+/411900 TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Robert Findley <[email protected]> Run-TryBot: Alan Donovan <[email protected]> gopls-CI: kokoro <[email protected]>
1 parent 63d8015 commit cbb8e8e

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

internal/span/uri.go

+21-4
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,29 @@ func (uri URI) Filename() string {
3535
}
3636

3737
func filename(uri URI) (string, error) {
38-
// This function is frequently called and its cost is
39-
// dominated by the allocation of a net.URL.
40-
// TODO(adonovan): opt: replace by a bespoke parseFileURI
41-
// function that doesn't allocate.
4238
if uri == "" {
4339
return "", nil
4440
}
41+
42+
// This conservative check for the common case
43+
// of a simple non-empty absolute POSIX filename
44+
// avoids the allocation of a net.URL.
45+
if strings.HasPrefix(string(uri), "file:///") {
46+
rest := string(uri)[len("file://"):] // leave one slash
47+
for i := 0; i < len(rest); i++ {
48+
b := rest[i]
49+
// Reject these cases:
50+
if b < ' ' || b == 0x7f || // control character
51+
b == '%' || b == '+' || // URI escape
52+
b == ':' || // Windows drive letter
53+
b == '@' || b == '&' || b == '?' { // authority or query
54+
goto slow
55+
}
56+
}
57+
return rest, nil
58+
}
59+
slow:
60+
4561
u, err := url.ParseRequestURI(string(uri))
4662
if err != nil {
4763
return "", err
@@ -54,6 +70,7 @@ func filename(uri URI) (string, error) {
5470
if isWindowsDriveURIPath(u.Path) {
5571
u.Path = strings.ToUpper(string(u.Path[1])) + u.Path[2:]
5672
}
73+
5774
return u.Path, nil
5875
}
5976

0 commit comments

Comments
 (0)