chore: update fast_XOR/AND/OR_Bytes optimization

This commit is contained in:
Sahil-4555 2025-10-12 13:25:53 +05:30
parent bceb7fabef
commit 55fdee27cd

View file

@ -27,36 +27,32 @@ func XORBytes(dst, a, b []byte) int {
// fastXORBytes xors in bulk. It only works on architectures that support // fastXORBytes xors in bulk. It only works on architectures that support
// unaligned read/writes. // unaligned read/writes.
func fastXORBytes(dst, a, b []byte) int { func fastXORBytes(dst, a, b []byte) int {
n := min(len(b), len(a)) n := min(len(a), len(b), len(dst))
if n == 0 {
w := n / wordSize return 0
}
if w > 0 { wordSize := int(unsafe.Sizeof(uintptr(0)))
dw := *(*[]uintptr)(unsafe.Pointer(&dst))
aw := *(*[]uintptr)(unsafe.Pointer(&a)) i := 0
bw := *(*[]uintptr)(unsafe.Pointer(&b)) for ; i < n && uintptr(unsafe.Pointer(&a[i]))%uintptr(wordSize) != 0; i++ {
dst[i] = a[i] ^ b[i]
i := 0 }
for i <= w-4 {
dw[i] = aw[i] ^ bw[i] w := (n - i) / wordSize
dw[i+1] = aw[i+1] ^ bw[i+1] if w > 0 {
dw[i+2] = aw[i+2] ^ bw[i+2] ad := unsafe.Slice((*uintptr)(unsafe.Pointer(&a[i])), w)
dw[i+3] = aw[i+3] ^ bw[i+3] bd := unsafe.Slice((*uintptr)(unsafe.Pointer(&b[i])), w)
i += 4 dd := unsafe.Slice((*uintptr)(unsafe.Pointer(&dst[i])), w)
} for j := 0; j < w; j++ {
// Handle remaining words dd[j] = ad[j] ^ bd[j]
for i < w { }
dw[i] = aw[i] ^ bw[i] i += w * wordSize
i++ }
}
} for ; i < n; i++ {
dst[i] = a[i] ^ b[i]
// Handle remaining bytes }
start := w * wordSize return n
for i := 0; i < n&(wordSize-1); i++ {
dst[start+i] = a[start+i] ^ b[start+i]
}
return n
} }
// safeXORBytes xors one by one. It works on all architectures, independent if // safeXORBytes xors one by one. It works on all architectures, independent if
@ -81,35 +77,32 @@ 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 := min(len(b), len(a)) n := min(len(a), len(b), len(dst))
w := n / wordSize if n == 0 {
return 0
if w > 0 { }
dw := *(*[]uintptr)(unsafe.Pointer(&dst)) wordSize := int(unsafe.Sizeof(uintptr(0)))
aw := *(*[]uintptr)(unsafe.Pointer(&a))
bw := *(*[]uintptr)(unsafe.Pointer(&b)) i := 0
for ; i < n && uintptr(unsafe.Pointer(&a[i]))%uintptr(wordSize) != 0; i++ {
i := 0 dst[i] = a[i] & b[i]
for i <= w-4 { }
dw[i] = aw[i] & bw[i]
dw[i+1] = aw[i+1] & bw[i+1] w := (n - i) / wordSize
dw[i+2] = aw[i+2] & bw[i+2] if w > 0 {
dw[i+3] = aw[i+3] & bw[i+3] ad := unsafe.Slice((*uintptr)(unsafe.Pointer(&a[i])), w)
i += 4 bd := unsafe.Slice((*uintptr)(unsafe.Pointer(&b[i])), w)
} dd := unsafe.Slice((*uintptr)(unsafe.Pointer(&dst[i])), w)
// Handle remaining words for j := 0; j < w; j++ {
for i < w { dd[j] = ad[j] & bd[j]
dw[i] = aw[i] & bw[i] }
i++ i += w * wordSize
} }
}
for ; i < n; i++ {
// Handle remaining bytes dst[i] = a[i] & b[i]
start := w * wordSize }
for i := 0; i < n&(wordSize-1); i++ { return n
dst[start+i] = a[start+i] & b[start+i]
}
return n
} }
// safeANDBytes ands one by one. It works on all architectures, independent if // safeANDBytes ands one by one. It works on all architectures, independent if
@ -134,34 +127,32 @@ func ORBytes(dst, a, b []byte) int {
// fastORBytes ors in bulk. It only works on architectures that support // fastORBytes ors in bulk. It only works on architectures that support
// unaligned read/writes. // unaligned read/writes.
func fastORBytes(dst, a, b []byte) int { func fastORBytes(dst, a, b []byte) int {
n := min(len(b), len(a)) n := min(len(a), len(b), len(dst))
w := n / wordSize if n == 0 {
if w > 0 { return 0
dw := *(*[]uintptr)(unsafe.Pointer(&dst)) }
aw := *(*[]uintptr)(unsafe.Pointer(&a)) wordSize := int(unsafe.Sizeof(uintptr(0)))
bw := *(*[]uintptr)(unsafe.Pointer(&b))
i := 0
i := 0 for ; i < n && uintptr(unsafe.Pointer(&a[i]))%uintptr(wordSize) != 0; i++ {
for i <= w-4 { dst[i] = a[i] | b[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] w := (n - i) / wordSize
dw[i+3] = aw[i+3] | bw[i+3] if w > 0 {
i += 4 ad := unsafe.Slice((*uintptr)(unsafe.Pointer(&a[i])), w)
} bd := unsafe.Slice((*uintptr)(unsafe.Pointer(&b[i])), w)
// Handle remaining words dd := unsafe.Slice((*uintptr)(unsafe.Pointer(&dst[i])), w)
for i < w { for j := 0; j < w; j++ {
dw[i] = aw[i] | bw[i] dd[j] = ad[j] | bd[j]
i++ }
} i += w * wordSize
} }
// Handle remaining bytes for ; i < n; i++ {
start := w * wordSize dst[i] = a[i] | b[i]
for i := 0; i < n&(wordSize-1); i++ { }
dst[start+i] = a[start+i] | b[start+i] return n
}
return n
} }
// safeORBytes ors one by one. It works on all architectures, independent if // safeORBytes ors one by one. It works on all architectures, independent if