Skip to content

Commit 3525c07

Browse files
committed
base64: avoid compliler boundary checks in the hot loop
Unfortunately compiler is not capable to realise that boundary checks are not necessary on each src[si+N] access. Selection of sub-slice helps. benchmark old MB/s new MB/s speedup BenchmarkEncodeToString-8 678.24 675.38 1.00x BenchmarkDecodeString/2-8 111.61 109.20 0.98x BenchmarkDecodeString/4-8 183.22 195.49 1.07x BenchmarkDecodeString/8-8 249.11 249.52 1.00x BenchmarkDecodeString/64-8 653.02 697.99 1.07x BenchmarkDecodeString/8192-8 950.17 1028.51 1.08x
1 parent 9ecefc4 commit 3525c07

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

src/encoding/base64/base64.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -488,15 +488,16 @@ func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
488488

489489
si := 0
490490
for strconv.IntSize >= 64 && len(src)-si >= 8 && len(dst)-n >= 8 {
491+
src2 := src[si : si+8]
491492
if dn, ok := assemble64(
492-
enc.decodeMap[src[si+0]],
493-
enc.decodeMap[src[si+1]],
494-
enc.decodeMap[src[si+2]],
495-
enc.decodeMap[src[si+3]],
496-
enc.decodeMap[src[si+4]],
497-
enc.decodeMap[src[si+5]],
498-
enc.decodeMap[src[si+6]],
499-
enc.decodeMap[src[si+7]],
493+
enc.decodeMap[src2[0]],
494+
enc.decodeMap[src2[1]],
495+
enc.decodeMap[src2[2]],
496+
enc.decodeMap[src2[3]],
497+
enc.decodeMap[src2[4]],
498+
enc.decodeMap[src2[5]],
499+
enc.decodeMap[src2[6]],
500+
enc.decodeMap[src2[7]],
500501
); ok {
501502
binary.BigEndian.PutUint64(dst[n:], dn)
502503
n += 6
@@ -512,11 +513,12 @@ func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
512513
}
513514

514515
for len(src)-si >= 4 && len(dst)-n >= 4 {
516+
src2 := src[si : si+4]
515517
if dn, ok := assemble32(
516-
enc.decodeMap[src[si+0]],
517-
enc.decodeMap[src[si+1]],
518-
enc.decodeMap[src[si+2]],
519-
enc.decodeMap[src[si+3]],
518+
enc.decodeMap[src2[0]],
519+
enc.decodeMap[src2[1]],
520+
enc.decodeMap[src2[2]],
521+
enc.decodeMap[src2[3]],
520522
); ok {
521523
binary.BigEndian.PutUint32(dst[n:], dn)
522524
n += 3

0 commit comments

Comments
 (0)