mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
bitutil: optimize fastANDBytes with bit shifts
This commit is contained in:
parent
d407dff272
commit
e77dc6511f
1 changed files with 22 additions and 14 deletions
|
|
@ -8,7 +8,6 @@
|
||||||
package bitutil
|
package bitutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/bits"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
@ -30,7 +29,7 @@ func XORBytes(dst, a, b []byte) int {
|
||||||
func fastXORBytes(dst, a, b []byte) int {
|
func fastXORBytes(dst, a, b []byte) int {
|
||||||
n := min(len(b), len(a))
|
n := min(len(b), len(a))
|
||||||
|
|
||||||
w := n >> bits.TrailingZeros(uint(wordSize))
|
w := n / wordSize
|
||||||
|
|
||||||
if w > 0 {
|
if w > 0 {
|
||||||
dw := *(*[]uintptr)(unsafe.Pointer(&dst))
|
dw := *(*[]uintptr)(unsafe.Pointer(&dst))
|
||||||
|
|
@ -82,21 +81,33 @@ func ANDBytes(dst, a, b []byte) int {
|
||||||
// fastANDBytes ands in bulk. It only works on architectures that support
|
// fastANDBytes ands in bulk. It only works on architectures that support
|
||||||
// unaligned read/writes.
|
// unaligned read/writes.
|
||||||
func fastANDBytes(dst, a, b []byte) int {
|
func fastANDBytes(dst, a, b []byte) int {
|
||||||
n := len(a)
|
n := min(len(b), len(a))
|
||||||
if len(b) < n {
|
|
||||||
n = len(b)
|
|
||||||
}
|
|
||||||
w := n / wordSize
|
w := n / wordSize
|
||||||
|
|
||||||
if w > 0 {
|
if w > 0 {
|
||||||
dw := *(*[]uintptr)(unsafe.Pointer(&dst))
|
dw := *(*[]uintptr)(unsafe.Pointer(&dst))
|
||||||
aw := *(*[]uintptr)(unsafe.Pointer(&a))
|
aw := *(*[]uintptr)(unsafe.Pointer(&a))
|
||||||
bw := *(*[]uintptr)(unsafe.Pointer(&b))
|
bw := *(*[]uintptr)(unsafe.Pointer(&b))
|
||||||
for i := 0; i < w; i++ {
|
|
||||||
|
i := 0
|
||||||
|
for i <= w-4 {
|
||||||
dw[i] = aw[i] & bw[i]
|
dw[i] = aw[i] & bw[i]
|
||||||
|
dw[i+1] = aw[i+1] & bw[i+1]
|
||||||
|
dw[i+2] = aw[i+2] & bw[i+2]
|
||||||
|
dw[i+3] = aw[i+3] & bw[i+3]
|
||||||
|
i += 4
|
||||||
|
}
|
||||||
|
// Handle remaining words
|
||||||
|
for i < w {
|
||||||
|
dw[i] = aw[i] & bw[i]
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := n - n%wordSize; i < n; i++ {
|
|
||||||
dst[i] = a[i] & b[i]
|
// Handle remaining bytes
|
||||||
|
start := w * wordSize
|
||||||
|
for i := 0; i < n&(wordSize-1); i++ {
|
||||||
|
dst[start+i] = a[start+i] & b[start+i]
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
@ -104,11 +115,8 @@ func fastANDBytes(dst, a, b []byte) int {
|
||||||
// safeANDBytes ands one by one. It works on all architectures, independent if
|
// safeANDBytes ands one by one. It works on all architectures, independent if
|
||||||
// it supports unaligned read/writes or not.
|
// it supports unaligned read/writes or not.
|
||||||
func safeANDBytes(dst, a, b []byte) int {
|
func safeANDBytes(dst, a, b []byte) int {
|
||||||
n := len(a)
|
n := min(len(b), len(a))
|
||||||
if len(b) < n {
|
for i := range n {
|
||||||
n = len(b)
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
dst[i] = a[i] & b[i]
|
dst[i] = a[i] & b[i]
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue