Skip to content

Commit

Permalink
net/url: use strings.IndexByte instead of strings.Index in split func…
Browse files Browse the repository at this point in the history
…tion

Production profiling shows ~15% of url.Parse time being spend in the overhead
of calling strings.IndexByte through strings.Index instead of calling
strings.IndexByte directly.

name   old time/op  new time/op  delta
Split  15.5ns ± 2%  10.7ns ± 3%  -30.98%  (p=0.000 n=20+19)

Change-Id: Ie25dd4afa93539a1335a91ab2a4a367f97bd3df0
Reviewed-on: https://go-review.googlesource.com/c/go/+/178877
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
  • Loading branch information
martisch authored and mvdan committed Aug 28, 2019
1 parent 6a73e94 commit 5ff12f6
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
20 changes: 10 additions & 10 deletions src/net/url/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,16 +449,16 @@ func getscheme(rawurl string) (scheme, path string, err error) {
return "", rawurl, nil
}

// Maybe s is of the form t c u.
// If so, return t, c u (or t, u if cutc == true).
// If not, return s, "".
func split(s string, c string, cutc bool) (string, string) {
i := strings.Index(s, c)
// split slices s into two substrings separated by the first occurence of
// sep. If cutc is true then sep is included with the second substring.
// If sep does not occur in s then s and the empty string is returned.
func split(s string, sep byte, cutc bool) (string, string) {
i := strings.IndexByte(s, sep)
if i < 0 {
return s, ""
}
if cutc {
return s[:i], s[i+len(c):]
return s[:i], s[i+1:]
}
return s[:i], s[i:]
}
Expand All @@ -471,7 +471,7 @@ func split(s string, c string, cutc bool) (string, string) {
// error, due to parsing ambiguities.
func Parse(rawurl string) (*URL, error) {
// Cut off #frag
u, frag := split(rawurl, "#", true)
u, frag := split(rawurl, '#', true)
url, err := parse(u, false)
if err != nil {
return nil, &Error{"parse", u, err}
Expand Down Expand Up @@ -531,7 +531,7 @@ func parse(rawurl string, viaRequest bool) (*URL, error) {
url.ForceQuery = true
rest = rest[:len(rest)-1]
} else {
rest, url.RawQuery = split(rest, "?", true)
rest, url.RawQuery = split(rest, '?', true)
}

if !strings.HasPrefix(rest, "/") {
Expand Down Expand Up @@ -560,7 +560,7 @@ func parse(rawurl string, viaRequest bool) (*URL, error) {

if (url.Scheme != "" || !viaRequest && !strings.HasPrefix(rest, "///")) && strings.HasPrefix(rest, "//") {
var authority string
authority, rest = split(rest[2:], "/", false)
authority, rest = split(rest[2:], '/', false)
url.User, url.Host, err = parseAuthority(authority)
if err != nil {
return nil, err
Expand Down Expand Up @@ -599,7 +599,7 @@ func parseAuthority(authority string) (user *Userinfo, host string, err error) {
}
user = User(userinfo)
} else {
username, password := split(userinfo, ":", true)
username, password := split(userinfo, ':', true)
if username, err = unescape(username, encodeUserPassword); err != nil {
return nil, "", err
}
Expand Down
9 changes: 9 additions & 0 deletions src/net/url/url_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1874,3 +1874,12 @@ func BenchmarkPathUnescape(b *testing.B) {
})
}
}

var sink string

func BenchmarkSplit(b *testing.B) {
url := "http://www.google.com/?q=go+language#foo%26bar"
for i := 0; i < b.N; i++ {
sink, sink = split(url, '#', true)
}
}

0 comments on commit 5ff12f6

Please sign in to comment.