mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-13 11:36:37 +00:00
Revert "rm bitutil xorbytes helper func"
This reverts commit 121c43075e.
This commit is contained in:
parent
1d268e86b5
commit
b80ffe98a5
2 changed files with 79 additions and 0 deletions
|
|
@ -8,6 +8,7 @@
|
||||||
package bitutil
|
package bitutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/subtle"
|
||||||
"runtime"
|
"runtime"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
@ -15,6 +16,19 @@ import (
|
||||||
const wordSize = int(unsafe.Sizeof(uintptr(0)))
|
const wordSize = int(unsafe.Sizeof(uintptr(0)))
|
||||||
const supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x"
|
const supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "s390x"
|
||||||
|
|
||||||
|
// XORBytes xors the bytes in a and b. The destination is assumed to have enough
|
||||||
|
// space. Returns the number of bytes xor'd.
|
||||||
|
//
|
||||||
|
// If dst does not have length at least n,
|
||||||
|
// XORBytes panics without writing anything to dst.
|
||||||
|
//
|
||||||
|
// dst and x or y may overlap exactly or not at all,
|
||||||
|
// otherwise XORBytes may panic.
|
||||||
|
//
|
||||||
|
// Deprecated: use crypto/subtle.XORBytes
|
||||||
|
func XORBytes(dst, a, b []byte) int {
|
||||||
|
return subtle.XORBytes(dst, a, b)
|
||||||
|
}
|
||||||
|
|
||||||
// ANDBytes ands the bytes in a and b. The destination is assumed to have enough
|
// ANDBytes ands the bytes in a and b. The destination is assumed to have enough
|
||||||
// space. Returns the number of bytes and'd.
|
// space. Returns the number of bytes and'd.
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,45 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Tests that bitwise XOR works for various alignments.
|
||||||
|
func TestXOR(t *testing.T) {
|
||||||
|
for alignP := 0; alignP < 2; alignP++ {
|
||||||
|
for alignQ := 0; alignQ < 2; alignQ++ {
|
||||||
|
for alignD := 0; alignD < 2; alignD++ {
|
||||||
|
p := make([]byte, 1023)[alignP:]
|
||||||
|
q := make([]byte, 1023)[alignQ:]
|
||||||
|
|
||||||
|
for i := 0; i < len(p); i++ {
|
||||||
|
p[i] = byte(i)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(q); i++ {
|
||||||
|
q[i] = byte(len(q) - i)
|
||||||
|
}
|
||||||
|
d1 := make([]byte, 1023+alignD)[alignD:]
|
||||||
|
d2 := make([]byte, 1023+alignD)[alignD:]
|
||||||
|
|
||||||
|
XORBytes(d1, p, q)
|
||||||
|
naiveXOR(d2, p, q)
|
||||||
|
if !bytes.Equal(d1, d2) {
|
||||||
|
t.Error("not equal", d1, d2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// naiveXOR xors bytes one by one.
|
||||||
|
func naiveXOR(dst, a, b []byte) int {
|
||||||
|
n := len(a)
|
||||||
|
if len(b) < n {
|
||||||
|
n = len(b)
|
||||||
|
}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
dst[i] = a[i] ^ b[i]
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that bitwise AND works for various alignments.
|
// Tests that bitwise AND works for various alignments.
|
||||||
func TestAND(t *testing.T) {
|
func TestAND(t *testing.T) {
|
||||||
for alignP := 0; alignP < 2; alignP++ {
|
for alignP := 0; alignP < 2; alignP++ {
|
||||||
|
|
@ -85,6 +124,32 @@ func TestTest(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Benchmarks the potentially optimized XOR performance.
|
||||||
|
func BenchmarkFastXOR1KB(b *testing.B) { benchmarkFastXOR(b, 1024) }
|
||||||
|
func BenchmarkFastXOR2KB(b *testing.B) { benchmarkFastXOR(b, 2048) }
|
||||||
|
func BenchmarkFastXOR4KB(b *testing.B) { benchmarkFastXOR(b, 4096) }
|
||||||
|
|
||||||
|
func benchmarkFastXOR(b *testing.B, size int) {
|
||||||
|
p, q := make([]byte, size), make([]byte, size)
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
XORBytes(p, p, q)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benchmarks the baseline XOR performance.
|
||||||
|
func BenchmarkBaseXOR1KB(b *testing.B) { benchmarkBaseXOR(b, 1024) }
|
||||||
|
func BenchmarkBaseXOR2KB(b *testing.B) { benchmarkBaseXOR(b, 2048) }
|
||||||
|
func BenchmarkBaseXOR4KB(b *testing.B) { benchmarkBaseXOR(b, 4096) }
|
||||||
|
|
||||||
|
func benchmarkBaseXOR(b *testing.B, size int) {
|
||||||
|
p, q := make([]byte, size), make([]byte, size)
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
naiveXOR(p, p, q)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Benchmarks the potentially optimized AND performance.
|
// Benchmarks the potentially optimized AND performance.
|
||||||
func BenchmarkFastAND1KB(b *testing.B) { benchmarkFastAND(b, 1024) }
|
func BenchmarkFastAND1KB(b *testing.B) { benchmarkFastAND(b, 1024) }
|
||||||
func BenchmarkFastAND2KB(b *testing.B) { benchmarkFastAND(b, 2048) }
|
func BenchmarkFastAND2KB(b *testing.B) { benchmarkFastAND(b, 2048) }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue