mirror of
https://github.com/golang/go
synced 2024-11-18 19:44:46 -07:00
net/url: use bytes.Buffer in (*URL).String
BenchmarkString before: 11990 ns/op 1621 B/op 73 allocs/op Using bytes.Buffer: 8774 ns/op 1994 B/op 40 allocs/op I also tried making a version of escape() that writes directly to the bytes.Buffer, but it only saved 1 alloc/op and increased CPU time by about 10%. Didn't seem worth the extra code path. R=bradfitz CC=golang-dev https://golang.org/cl/7182050
This commit is contained in:
parent
cdd6ae1288
commit
da82dfaccd
@ -434,32 +434,35 @@ func parseAuthority(authority string) (user *Userinfo, host string, err error) {
|
|||||||
|
|
||||||
// String reassembles the URL into a valid URL string.
|
// String reassembles the URL into a valid URL string.
|
||||||
func (u *URL) String() string {
|
func (u *URL) String() string {
|
||||||
// TODO: Rewrite to use bytes.Buffer
|
var buf bytes.Buffer
|
||||||
result := ""
|
|
||||||
if u.Scheme != "" {
|
if u.Scheme != "" {
|
||||||
result += u.Scheme + ":"
|
buf.WriteString(u.Scheme)
|
||||||
|
buf.WriteByte(':')
|
||||||
}
|
}
|
||||||
if u.Opaque != "" {
|
if u.Opaque != "" {
|
||||||
result += u.Opaque
|
buf.WriteString(u.Opaque)
|
||||||
} else {
|
} else {
|
||||||
if u.Scheme != "" || u.Host != "" || u.User != nil {
|
if u.Scheme != "" || u.Host != "" || u.User != nil {
|
||||||
result += "//"
|
buf.WriteString("//")
|
||||||
if u := u.User; u != nil {
|
if u := u.User; u != nil {
|
||||||
result += u.String() + "@"
|
buf.WriteString(u.String())
|
||||||
|
buf.WriteByte('@')
|
||||||
}
|
}
|
||||||
if h := u.Host; h != "" {
|
if h := u.Host; h != "" {
|
||||||
result += u.Host
|
buf.WriteString(h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result += escape(u.Path, encodePath)
|
buf.WriteString(escape(u.Path, encodePath))
|
||||||
}
|
}
|
||||||
if u.RawQuery != "" {
|
if u.RawQuery != "" {
|
||||||
result += "?" + u.RawQuery
|
buf.WriteByte('?')
|
||||||
|
buf.WriteString(u.RawQuery)
|
||||||
}
|
}
|
||||||
if u.Fragment != "" {
|
if u.Fragment != "" {
|
||||||
result += "#" + escape(u.Fragment, encodeFragment)
|
buf.WriteByte('#')
|
||||||
|
buf.WriteString(escape(u.Fragment, encodeFragment))
|
||||||
}
|
}
|
||||||
return result
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Values maps a string key to a list of values.
|
// Values maps a string key to a list of values.
|
||||||
|
@ -280,6 +280,30 @@ func DoTest(t *testing.T, parse func(string) (*URL, error), name string, tests [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkString(b *testing.B) {
|
||||||
|
b.StopTimer()
|
||||||
|
b.ReportAllocs()
|
||||||
|
for _, tt := range urltests {
|
||||||
|
u, err := Parse(tt.in)
|
||||||
|
if err != nil {
|
||||||
|
b.Errorf("Parse(%q) returned error %s", tt.in, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if tt.roundtrip == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
b.StartTimer()
|
||||||
|
var g string
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
g = u.String()
|
||||||
|
}
|
||||||
|
b.StopTimer()
|
||||||
|
if w := tt.roundtrip; g != w {
|
||||||
|
b.Errorf("Parse(%q).String() == %q, want %q", tt.in, g, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
func TestParse(t *testing.T) {
|
||||||
DoTest(t, Parse, "Parse", urltests)
|
DoTest(t, Parse, "Parse", urltests)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user