From: ErikPelli Date: Sun, 14 Aug 2022 07:46:22 +0000 (+0000) Subject: encoding/base64: optimize decodemap memory set X-Git-Tag: go1.20rc1~1605 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e1b62efaf33988a5153510898d37309cee78f26e;p=gostls13.git encoding/base64: optimize decodemap memory set The existing implementation has an execution time higher in the benchmark than this one. This is an optimized implementation using the copy() function and a constant 256 bytes string with the values to be copied. ``` name old time/op new time/op delta NewEncoding-4 329ns ± 1% 231ns ± 1% -29.72% (p=0.008 n=5+5) name old speed new speed delta NewEncoding-4 778MB/s ± 1% 1108MB/s ± 1% +42.29% (p=0.008 n=5+5) ``` Fixes #53211 Change-Id: I80fe62aa40623125ef81ae9164a8405eed30b71b GitHub-Last-Rev: 55dce6f636ad29a70daa935169710c22f44ab31f GitHub-Pull-Request: golang/go#53212 Reviewed-on: https://go-review.googlesource.com/c/go/+/410194 Reviewed-by: Keith Randall Run-TryBot: Keith Randall TryBot-Result: Gopher Robot Reviewed-by: Keith Randall Auto-Submit: Keith Randall Reviewed-by: Ian Lance Taylor --- diff --git a/src/encoding/base32/base32.go b/src/encoding/base32/base32.go index fa6e42e26c..41d343aaac 100644 --- a/src/encoding/base32/base32.go +++ b/src/encoding/base32/base32.go @@ -25,8 +25,25 @@ type Encoding struct { } const ( - StdPadding rune = '=' // Standard padding character - NoPadding rune = -1 // No padding + StdPadding rune = '=' // Standard padding character + NoPadding rune = -1 // No padding + decodeMapInitialize = "" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" ) const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" @@ -40,12 +57,10 @@ func NewEncoding(encoder string) *Encoding { } e := new(Encoding) - copy(e.encode[:], encoder) e.padChar = StdPadding + copy(e.encode[:], encoder) + copy(e.decodeMap[:], decodeMapInitialize) - for i := 0; i < len(e.decodeMap); i++ { - e.decodeMap[i] = 0xFF - } for i := 0; i < len(encoder); i++ { e.decodeMap[encoder[i]] = byte(i) } diff --git a/src/encoding/base64/base64.go b/src/encoding/base64/base64.go index 4a3e590649..0e12d90d29 100644 --- a/src/encoding/base64/base64.go +++ b/src/encoding/base64/base64.go @@ -28,8 +28,25 @@ type Encoding struct { } const ( - StdPadding rune = '=' // Standard padding character - NoPadding rune = -1 // No padding + StdPadding rune = '=' // Standard padding character + NoPadding rune = -1 // No padding + decodeMapInitialize = "" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" ) const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" @@ -53,10 +70,8 @@ func NewEncoding(encoder string) *Encoding { e := new(Encoding) e.padChar = StdPadding copy(e.encode[:], encoder) + copy(e.decodeMap[:], decodeMapInitialize) - for i := 0; i < len(e.decodeMap); i++ { - e.decodeMap[i] = 0xFF - } for i := 0; i < len(encoder); i++ { e.decodeMap[encoder[i]] = byte(i) } diff --git a/src/encoding/base64/base64_test.go b/src/encoding/base64/base64_test.go index 57256a3846..852446dd8b 100644 --- a/src/encoding/base64/base64_test.go +++ b/src/encoding/base64/base64_test.go @@ -504,6 +504,16 @@ func BenchmarkDecodeString(b *testing.B) { } } +func BenchmarkNewEncoding(b *testing.B) { + b.SetBytes(int64(len(Encoding{}.decodeMap))) + for i := 0; i < b.N; i++ { + e := NewEncoding(encodeStd) + for _, v := range e.decodeMap { + _ = v + } + } +} + func TestDecoderRaw(t *testing.T) { source := "AAAAAA" want := []byte{0, 0, 0, 0}