aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/base64
diff options
context:
space:
mode:
authorDaniel Martí <mvdan@mvdan.cc>2018-11-25 14:53:24 +0000
committerDaniel Martí <mvdan@mvdan.cc>2019-03-03 10:33:18 +0000
commitfc42cf8b8ccf6753c01e063ac090b2a60e70f077 (patch)
tree9ccacc910eac96bc7ae7ea481e9c0b3417c3e96a /src/encoding/base64
parent3de2fb21b7b4d472637f83031ec48e9bf539a4ee (diff)
downloadgo-fc42cf8b8ccf6753c01e063ac090b2a60e70f077.tar.gz
go-fc42cf8b8ccf6753c01e063ac090b2a60e70f077.zip
encoding/base64: lift nil check out of encode loop
Most of the encoding time is spent in the first Encode loop, since the rest of the function only deals with the few remaining bytes. Any unnecessary work done in that loop body matters tremendously. One such unnecessary bottleneck was the use of the enc.encode table. Since enc is a pointer receiver, and the field is first used within the loop, the encoder must perform a nil check at every iteration. Add a dummy use of the field before the start of the loop, to move the nil check there. After that line, the compiler now knows that enc can't be nil, and thus the hot loop is free of nil checks. name old time/op new time/op delta EncodeToString-4 14.7µs ± 0% 13.7µs ± 1% -6.53% (p=0.000 n=10+10) name old speed new speed delta EncodeToString-4 559MB/s ± 0% 598MB/s ± 1% +6.99% (p=0.000 n=10+10) Updates #20206. Change-Id: Icbb523a7bd9e470a8be0a448d1d78ade97ed4ff6 Reviewed-on: https://go-review.googlesource.com/c/151158 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/encoding/base64')
-rw-r--r--src/encoding/base64/base64.go4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/encoding/base64/base64.go b/src/encoding/base64/base64.go
index 0bb37b311a..a90e4dfa12 100644
--- a/src/encoding/base64/base64.go
+++ b/src/encoding/base64/base64.go
@@ -123,6 +123,10 @@ func (enc *Encoding) Encode(dst, src []byte) {
if len(src) == 0 {
return
}
+ // enc is a pointer receiver, so the use of enc.encode within the hot
+ // loop below means a nil check at every operation. Lift that nil check
+ // outside of the loop to speed up the encoder.
+ _ = enc.encode
di, si := 0, 0
n := (len(src) / 3) * 3