From acc2ce075982cea15636f018c421f96105049282 Mon Sep 17 00:00:00 2001 From: Julien Cretel Date: Sat, 28 Mar 2026 15:18:23 +0000 Subject: encoding/hex: speed up Decode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL eliminates the remaining bounds check for index expressions on Encode's src parameter within the function's loop. Here are some benchmark results (no change to allocations): goos: darwin goarch: arm64 pkg: encoding/hex cpu: Apple M4 │ old │ new │ │ sec/op │ sec/op vs base │ Decode/256-10 166.2n ± 0% 142.9n ± 0% -14.02% (n=180) Decode/1024-10 626.9n ± 0% 532.7n ± 0% -15.03% (n=180) Decode/4096-10 2.472µ ± 0% 2.079µ ± 0% -15.90% (n=180) Decode/16384-10 9.843µ ± 0% 8.266µ ± 0% -16.02% (n=180) geomean 1.262µ 1.069µ -15.25% │ old │ new │ │ B/s │ B/s vs base │ Decode/256-10 1.434Gi ± 0% 1.669Gi ± 0% +16.32% (p=0.000 n=180) Decode/1024-10 1.521Gi ± 0% 1.790Gi ± 0% +17.69% (p=0.000 n=180) Decode/4096-10 1.543Gi ± 0% 1.834Gi ± 0% +18.87% (p=0.000 n=180) Decode/16384-10 1.550Gi ± 0% 1.846Gi ± 0% +19.08% (p=0.000 n=180) geomean 1.512Gi 1.783Gi +17.98% Change-Id: Ibf0471a75087feed528e6b547c7c2c88c6e14d38 GitHub-Last-Rev: dcda1b6a81011649d08db5093f38b12d1ac52f7d GitHub-Pull-Request: golang/go#78436 Reviewed-on: https://go-review.googlesource.com/c/go/+/760781 Auto-Submit: Keith Randall LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall Reviewed-by: Dmitri Shuralyov Reviewed-by: Keith Randall --- src/encoding/hex/hex.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/encoding/hex') diff --git a/src/encoding/hex/hex.go b/src/encoding/hex/hex.go index ba9cc0f967..4499974325 100644 --- a/src/encoding/hex/hex.go +++ b/src/encoding/hex/hex.go @@ -85,10 +85,10 @@ func DecodedLen(x int) int { return x / 2 } // If the input is malformed, Decode returns the number // of bytes decoded before the error. func Decode(dst, src []byte) (int, error) { - i, j := 0, 1 - for ; j < len(src); j += 2 { - p := src[j-1] - q := src[j] + i, j := 0, 0 + for ; j < len(src)-1; j += 2 { + p := src[j] + q := src[j+1] a := reverseHexTable[p] b := reverseHexTable[q] @@ -104,8 +104,8 @@ func Decode(dst, src []byte) (int, error) { if len(src)%2 == 1 { // Check for invalid char before reporting bad length, // since the invalid char (if present) is an earlier problem. - if reverseHexTable[src[j-1]] > 0x0f { - return i, InvalidByteError(src[j-1]) + if reverseHexTable[src[j]] > 0x0f { + return i, InvalidByteError(src[j]) } return i, ErrLength } -- cgit v1.3-5-g9baa