forked from mirror/brotli
Read multiple bytes in findMatchLengthWithLimit
Use 64- or 32-bit loads instead of reading a byte at a time. The original C source did something like this, in a very C-ish way. It needed to be simplified to translate it to Go. The exact way this works was suggested by the assembly code in github.com/golang/snappy.
This commit is contained in:
parent
a01a7b12c9
commit
8f8b18645c
|
@ -461,8 +461,9 @@ func BenchmarkEncodeLevelsReset(b *testing.B) {
|
||||||
w := NewWriterLevel(buf, level)
|
w := NewWriterLevel(buf, level)
|
||||||
w.Write(opticks)
|
w.Write(opticks)
|
||||||
w.Close()
|
w.Close()
|
||||||
b.Run(fmt.Sprintf("%d(%.1f%%)", level, float64(buf.Len())/float64(len(opticks))*100), func(b *testing.B) {
|
b.Run(fmt.Sprintf("%d", level), func(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
b.ReportMetric(float64(len(opticks))/float64(buf.Len()), "ratio")
|
||||||
b.SetBytes(int64(len(opticks)))
|
b.SetBytes(int64(len(opticks)))
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
w.Reset(ioutil.Discard)
|
w.Reset(ioutil.Discard)
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
package brotli
|
package brotli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"math/bits"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
/* Copyright 2010 Google Inc. All Rights Reserved.
|
/* Copyright 2010 Google Inc. All Rights Reserved.
|
||||||
|
|
||||||
Distributed under MIT license.
|
Distributed under MIT license.
|
||||||
|
@ -10,6 +16,28 @@ package brotli
|
||||||
func findMatchLengthWithLimit(s1 []byte, s2 []byte, limit uint) uint {
|
func findMatchLengthWithLimit(s1 []byte, s2 []byte, limit uint) uint {
|
||||||
var matched uint = 0
|
var matched uint = 0
|
||||||
_, _ = s1[limit-1], s2[limit-1] // bounds check
|
_, _ = s1[limit-1], s2[limit-1] // bounds check
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "amd64":
|
||||||
|
// Compare 8 bytes at at time.
|
||||||
|
for matched+8 <= limit {
|
||||||
|
w1 := binary.LittleEndian.Uint64(s1[matched:])
|
||||||
|
w2 := binary.LittleEndian.Uint64(s2[matched:])
|
||||||
|
if w1 != w2 {
|
||||||
|
return matched + uint(bits.TrailingZeros64(w1^w2)>>3)
|
||||||
|
}
|
||||||
|
matched += 8
|
||||||
|
}
|
||||||
|
case "386":
|
||||||
|
// Compare 4 bytes at at time.
|
||||||
|
for matched+4 <= limit {
|
||||||
|
w1 := binary.LittleEndian.Uint32(s1[matched:])
|
||||||
|
w2 := binary.LittleEndian.Uint32(s2[matched:])
|
||||||
|
if w1 != w2 {
|
||||||
|
return matched + uint(bits.TrailingZeros32(w1^w2)>>3)
|
||||||
|
}
|
||||||
|
matched += 4
|
||||||
|
}
|
||||||
|
}
|
||||||
for matched < limit && s1[matched] == s2[matched] {
|
for matched < limit && s1[matched] == s2[matched] {
|
||||||
matched++
|
matched++
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue