Commit a563f2f4 authored by Daniel Martí's avatar Daniel Martí

encoding/hex: simplify encoder arithmetic

Two additions are faster than two multiplications and one addition. The
code seems simpler to me too, as it's more obvious that we advance two
destination bytes for each source byte.

name            old time/op  new time/op  delta
Encode/256-8     374ns ± 0%   331ns ± 0%  -11.44%  (p=0.008 n=5+5)
Encode/1024-8   1.47µs ± 0%  1.29µs ± 0%  -11.89%  (p=0.004 n=6+5)
Encode/4096-8   5.85µs ± 1%  5.15µs ± 0%  -11.89%  (p=0.004 n=6+5)
Encode/16384-8  23.3µs ± 0%  20.6µs ± 0%  -11.68%  (p=0.004 n=6+5)

Change-Id: Iabc63616c1d9fded55fa668ff41dd49efeaa2ea4
Reviewed-on: https://go-review.googlesource.com/c/go/+/151198
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarroger peppe <rogpeppe@gmail.com>
parent ebdc24c3
...@@ -23,11 +23,12 @@ func EncodedLen(n int) int { return n * 2 } ...@@ -23,11 +23,12 @@ func EncodedLen(n int) int { return n * 2 }
// of bytes written to dst, but this value is always EncodedLen(len(src)). // of bytes written to dst, but this value is always EncodedLen(len(src)).
// Encode implements hexadecimal encoding. // Encode implements hexadecimal encoding.
func Encode(dst, src []byte) int { func Encode(dst, src []byte) int {
for i, v := range src { j := 0
dst[i*2] = hextable[v>>4] for _, v := range src {
dst[i*2+1] = hextable[v&0x0f] dst[j] = hextable[v>>4]
dst[j+1] = hextable[v&0x0f]
j += 2
} }
return len(src) * 2 return len(src) * 2
} }
......
...@@ -242,6 +242,7 @@ func BenchmarkEncode(b *testing.B) { ...@@ -242,6 +242,7 @@ func BenchmarkEncode(b *testing.B) {
sink = make([]byte, 2*size) sink = make([]byte, 2*size)
b.Run(fmt.Sprintf("%v", size), func(b *testing.B) { b.Run(fmt.Sprintf("%v", size), func(b *testing.B) {
b.SetBytes(int64(size))
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Encode(sink, src) Encode(sink, src)
} }
...@@ -269,6 +270,7 @@ func BenchmarkDump(b *testing.B) { ...@@ -269,6 +270,7 @@ func BenchmarkDump(b *testing.B) {
sink = make([]byte, 2*size) sink = make([]byte, 2*size)
b.Run(fmt.Sprintf("%v", size), func(b *testing.B) { b.Run(fmt.Sprintf("%v", size), func(b *testing.B) {
b.SetBytes(int64(size))
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Dump(src) Dump(src)
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment