Build result string via string.Builder to avoid allocation.
As side effect some performance boots.
name old time/op new time/op delta
QueryUnescape/#00-4 114ns ± 0% 98ns ± 1% -13.89% (p=0.000 n=4+5)
QueryUnescape/#01-4 401ns ± 2% 383ns ± 1% -4.54% (p=0.008 n=5+5)
QueryUnescape/#02-4 300ns ± 2% 274ns ± 2% -8.66% (p=0.008 n=5+5)
QueryUnescape/#03-4 564ns ± 2% 542ns ± 2% -4.04% (p=0.008 n=5+5)
QueryUnescape/#04-4 3.27µs ± 2% 3.34µs ± 8% ~ (p=0.690 n=5+5)
PathUnescape/#00-4 112ns ± 2% 99ns ± 3% -11.25% (p=0.008 n=5+5)
PathUnescape/#01-4 392ns ± 2% 374ns ± 6% ~ (p=0.063 n=5+5)
PathUnescape/#02-4 296ns ± 2% 274ns ± 2% -7.43% (p=0.008 n=5+5)
PathUnescape/#03-4 556ns ± 2% 537ns ± 1% -3.45% (p=0.008 n=5+5)
PathUnescape/#04-4 2.99µs ± 1% 3.00µs ± 1% ~ (p=0.690 n=5+5)
name old allocs/op new allocs/op delta
QueryUnescape/#00-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
QueryUnescape/#01-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
QueryUnescape/#02-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
QueryUnescape/#03-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
QueryUnescape/#04-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
PathUnescape/#00-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
PathUnescape/#01-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
PathUnescape/#02-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
PathUnescape/#03-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
PathUnescape/#04-4 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.008 n=5+5)
Change-Id: I7cba5eb53bebef7b1fdd44598eed47241ce83167
Reviewed-on: https://go-review.googlesource.com/c/go/+/166463
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
return s, nil
}
- t := make([]byte, len(s)-2*n)
- j := 0
- for i := 0; i < len(s); {
+ var t strings.Builder
+ t.Grow(len(s) - 2*n)
+ for i := 0; i < len(s); i++ {
switch s[i] {
case '%':
- t[j] = unhex(s[i+1])<<4 | unhex(s[i+2])
- j++
- i += 3
+ t.WriteByte(unhex(s[i+1])<<4 | unhex(s[i+2]))
+ i += 2
case '+':
if mode == encodeQueryComponent {
- t[j] = ' '
+ t.WriteByte(' ')
} else {
- t[j] = '+'
+ t.WriteByte('+')
}
- j++
- i++
default:
- t[j] = s[i]
- j++
- i++
+ t.WriteByte(s[i])
}
}
- return string(t), nil
+ return t.String(), nil
}
// QueryEscape escapes the string so it can be safely placed