ccitt: speed up the highBits function Also fix s/PackBits/HighBits/ typos in reader_test.go. name old time/op new time/op delta HighBits-4 34.8µs ± 2% 11.0µs ± 1% -68.45% (p=0.008 n=5+5) Change-Id: Id5af14536edb66c5313b6fcf711872e5025cb503 Reviewed-on: https://go-review.googlesource.com/c/image/+/191941 Run-TryBot: Nigel Tao <nigeltao@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Horst Rutter <hhrutter@gmail.com> Reviewed-by: Benny Siegert <bsiegert@gmail.com>
diff --git a/ccitt/reader.go b/ccitt/reader.go index 792a9ce..df14833 100644 --- a/ccitt/reader.go +++ b/ccitt/reader.go
@@ -88,24 +88,37 @@ // are typically temporary, e.g. they will be flipped back to 0s by an // invertBytes call in the highBits caller, reader.Read. func highBits(dst []byte, src []byte, invert bool) (d int, s int) { - for d < len(dst) { - numToPack := len(src) - s - if numToPack <= 0 { - break - } else if numToPack > 8 { - numToPack = 8 - } + // Pack as many complete groups of 8 src bytes as we can. + n := len(src) / 8 + if n > len(dst) { + n = len(dst) + } + dstN := dst[:n] + for i := range dstN { + src8 := src[i*8 : i*8+8] + dstN[i] = ((src8[0] & 0x80) >> 0) | + ((src8[1] & 0x80) >> 1) | + ((src8[2] & 0x80) >> 2) | + ((src8[3] & 0x80) >> 3) | + ((src8[4] & 0x80) >> 4) | + ((src8[5] & 0x80) >> 5) | + ((src8[6] & 0x80) >> 6) | + ((src8[7] & 0x80) >> 7) + } + d, s = n, 8*n + dst, src = dst[d:], src[s:] - byteValue := byte(0) + // Pack up to 7 remaining src bytes, if there's room in dst. + if (len(dst) > 0) && (len(src) > 0) { + dstByte := byte(0) if invert { - byteValue = 0xFF >> uint(numToPack) + dstByte = 0xFF >> uint(len(src)) } - for n := 0; n < numToPack; n++ { - byteValue |= (src[s] & 0x80) >> uint(n) - s++ + for n, srcByte := range src { + dstByte |= (srcByte & 0x80) >> uint(n) } - dst[d] = byteValue - d++ + dst[0] = dstByte + d, s = d+1, s+len(src) } return d, s }
diff --git a/ccitt/reader_test.go b/ccitt/reader_test.go index 80c0e9f..01fcff0 100644 --- a/ccitt/reader_test.go +++ b/ccitt/reader_test.go
@@ -73,7 +73,7 @@ return d, s } -func TestPackBits(t *testing.T) { +func TestHighBits(t *testing.T) { rng := rand.New(rand.NewSource(1)) dst0 := make([]byte, 3) dst1 := make([]byte, 3) @@ -114,7 +114,7 @@ } } -func BenchmarkPackBits(b *testing.B) { +func BenchmarkHighBits(b *testing.B) { rng := rand.New(rand.NewSource(1)) dst := make([]byte, 1024) src := make([]byte, 7777)