github.com/ethxdao/go-ethereum@v0.0.0-20221218102228-5ae34a9cc189/common/bitutil/bitutil_test.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Adapted from: https://golang.org/src/crypto/cipher/xor_test.go
     6  
     7  package bitutil
     8  
     9  import (
    10  	"bytes"
    11  	"testing"
    12  )
    13  
    14  // Tests that bitwise XOR works for various alignments.
    15  func TestXOR(t *testing.T) {
    16  	for alignP := 0; alignP < 2; alignP++ {
    17  		for alignQ := 0; alignQ < 2; alignQ++ {
    18  			for alignD := 0; alignD < 2; alignD++ {
    19  				p := make([]byte, 1023)[alignP:]
    20  				q := make([]byte, 1023)[alignQ:]
    21  
    22  				for i := 0; i < len(p); i++ {
    23  					p[i] = byte(i)
    24  				}
    25  				for i := 0; i < len(q); i++ {
    26  					q[i] = byte(len(q) - i)
    27  				}
    28  				d1 := make([]byte, 1023+alignD)[alignD:]
    29  				d2 := make([]byte, 1023+alignD)[alignD:]
    30  
    31  				XORBytes(d1, p, q)
    32  				safeXORBytes(d2, p, q)
    33  				if !bytes.Equal(d1, d2) {
    34  					t.Error("not equal", d1, d2)
    35  				}
    36  			}
    37  		}
    38  	}
    39  }
    40  
    41  // Tests that bitwise AND works for various alignments.
    42  func TestAND(t *testing.T) {
    43  	for alignP := 0; alignP < 2; alignP++ {
    44  		for alignQ := 0; alignQ < 2; alignQ++ {
    45  			for alignD := 0; alignD < 2; alignD++ {
    46  				p := make([]byte, 1023)[alignP:]
    47  				q := make([]byte, 1023)[alignQ:]
    48  
    49  				for i := 0; i < len(p); i++ {
    50  					p[i] = byte(i)
    51  				}
    52  				for i := 0; i < len(q); i++ {
    53  					q[i] = byte(len(q) - i)
    54  				}
    55  				d1 := make([]byte, 1023+alignD)[alignD:]
    56  				d2 := make([]byte, 1023+alignD)[alignD:]
    57  
    58  				ANDBytes(d1, p, q)
    59  				safeANDBytes(d2, p, q)
    60  				if !bytes.Equal(d1, d2) {
    61  					t.Error("not equal")
    62  				}
    63  			}
    64  		}
    65  	}
    66  }
    67  
    68  // Tests that bitwise OR works for various alignments.
    69  func TestOR(t *testing.T) {
    70  	for alignP := 0; alignP < 2; alignP++ {
    71  		for alignQ := 0; alignQ < 2; alignQ++ {
    72  			for alignD := 0; alignD < 2; alignD++ {
    73  				p := make([]byte, 1023)[alignP:]
    74  				q := make([]byte, 1023)[alignQ:]
    75  
    76  				for i := 0; i < len(p); i++ {
    77  					p[i] = byte(i)
    78  				}
    79  				for i := 0; i < len(q); i++ {
    80  					q[i] = byte(len(q) - i)
    81  				}
    82  				d1 := make([]byte, 1023+alignD)[alignD:]
    83  				d2 := make([]byte, 1023+alignD)[alignD:]
    84  
    85  				ORBytes(d1, p, q)
    86  				safeORBytes(d2, p, q)
    87  				if !bytes.Equal(d1, d2) {
    88  					t.Error("not equal")
    89  				}
    90  			}
    91  		}
    92  	}
    93  }
    94  
    95  // Tests that bit testing works for various alignments.
    96  func TestTest(t *testing.T) {
    97  	for align := 0; align < 2; align++ {
    98  		// Test for bits set in the bulk part
    99  		p := make([]byte, 1023)[align:]
   100  		p[100] = 1
   101  
   102  		if TestBytes(p) != safeTestBytes(p) {
   103  			t.Error("not equal")
   104  		}
   105  		// Test for bits set in the tail part
   106  		q := make([]byte, 1023)[align:]
   107  		q[len(q)-1] = 1
   108  
   109  		if TestBytes(q) != safeTestBytes(q) {
   110  			t.Error("not equal")
   111  		}
   112  	}
   113  }
   114  
   115  // Benchmarks the potentially optimized XOR performance.
   116  func BenchmarkFastXOR1KB(b *testing.B) { benchmarkFastXOR(b, 1024) }
   117  func BenchmarkFastXOR2KB(b *testing.B) { benchmarkFastXOR(b, 2048) }
   118  func BenchmarkFastXOR4KB(b *testing.B) { benchmarkFastXOR(b, 4096) }
   119  
   120  func benchmarkFastXOR(b *testing.B, size int) {
   121  	p, q := make([]byte, size), make([]byte, size)
   122  
   123  	for i := 0; i < b.N; i++ {
   124  		XORBytes(p, p, q)
   125  	}
   126  }
   127  
   128  // Benchmarks the baseline XOR performance.
   129  func BenchmarkBaseXOR1KB(b *testing.B) { benchmarkBaseXOR(b, 1024) }
   130  func BenchmarkBaseXOR2KB(b *testing.B) { benchmarkBaseXOR(b, 2048) }
   131  func BenchmarkBaseXOR4KB(b *testing.B) { benchmarkBaseXOR(b, 4096) }
   132  
   133  func benchmarkBaseXOR(b *testing.B, size int) {
   134  	p, q := make([]byte, size), make([]byte, size)
   135  
   136  	for i := 0; i < b.N; i++ {
   137  		safeXORBytes(p, p, q)
   138  	}
   139  }
   140  
   141  // Benchmarks the potentially optimized AND performance.
   142  func BenchmarkFastAND1KB(b *testing.B) { benchmarkFastAND(b, 1024) }
   143  func BenchmarkFastAND2KB(b *testing.B) { benchmarkFastAND(b, 2048) }
   144  func BenchmarkFastAND4KB(b *testing.B) { benchmarkFastAND(b, 4096) }
   145  
   146  func benchmarkFastAND(b *testing.B, size int) {
   147  	p, q := make([]byte, size), make([]byte, size)
   148  
   149  	for i := 0; i < b.N; i++ {
   150  		ANDBytes(p, p, q)
   151  	}
   152  }
   153  
   154  // Benchmarks the baseline AND performance.
   155  func BenchmarkBaseAND1KB(b *testing.B) { benchmarkBaseAND(b, 1024) }
   156  func BenchmarkBaseAND2KB(b *testing.B) { benchmarkBaseAND(b, 2048) }
   157  func BenchmarkBaseAND4KB(b *testing.B) { benchmarkBaseAND(b, 4096) }
   158  
   159  func benchmarkBaseAND(b *testing.B, size int) {
   160  	p, q := make([]byte, size), make([]byte, size)
   161  
   162  	for i := 0; i < b.N; i++ {
   163  		safeANDBytes(p, p, q)
   164  	}
   165  }
   166  
   167  // Benchmarks the potentially optimized OR performance.
   168  func BenchmarkFastOR1KB(b *testing.B) { benchmarkFastOR(b, 1024) }
   169  func BenchmarkFastOR2KB(b *testing.B) { benchmarkFastOR(b, 2048) }
   170  func BenchmarkFastOR4KB(b *testing.B) { benchmarkFastOR(b, 4096) }
   171  
   172  func benchmarkFastOR(b *testing.B, size int) {
   173  	p, q := make([]byte, size), make([]byte, size)
   174  
   175  	for i := 0; i < b.N; i++ {
   176  		ORBytes(p, p, q)
   177  	}
   178  }
   179  
   180  // Benchmarks the baseline OR performance.
   181  func BenchmarkBaseOR1KB(b *testing.B) { benchmarkBaseOR(b, 1024) }
   182  func BenchmarkBaseOR2KB(b *testing.B) { benchmarkBaseOR(b, 2048) }
   183  func BenchmarkBaseOR4KB(b *testing.B) { benchmarkBaseOR(b, 4096) }
   184  
   185  func benchmarkBaseOR(b *testing.B, size int) {
   186  	p, q := make([]byte, size), make([]byte, size)
   187  
   188  	for i := 0; i < b.N; i++ {
   189  		safeORBytes(p, p, q)
   190  	}
   191  }
   192  
   193  var GloBool bool // Exported global will not be dead-code eliminated, at least not yet.
   194  
   195  // Benchmarks the potentially optimized bit testing performance.
   196  func BenchmarkFastTest1KB(b *testing.B) { benchmarkFastTest(b, 1024) }
   197  func BenchmarkFastTest2KB(b *testing.B) { benchmarkFastTest(b, 2048) }
   198  func BenchmarkFastTest4KB(b *testing.B) { benchmarkFastTest(b, 4096) }
   199  
   200  func benchmarkFastTest(b *testing.B, size int) {
   201  	p := make([]byte, size)
   202  	a := false
   203  	for i := 0; i < b.N; i++ {
   204  		a = a != TestBytes(p)
   205  	}
   206  	GloBool = a // Use of benchmark "result" to prevent total dead code elimination.
   207  }
   208  
   209  // Benchmarks the baseline bit testing performance.
   210  func BenchmarkBaseTest1KB(b *testing.B) { benchmarkBaseTest(b, 1024) }
   211  func BenchmarkBaseTest2KB(b *testing.B) { benchmarkBaseTest(b, 2048) }
   212  func BenchmarkBaseTest4KB(b *testing.B) { benchmarkBaseTest(b, 4096) }
   213  
   214  func benchmarkBaseTest(b *testing.B, size int) {
   215  	p := make([]byte, size)
   216  	a := false
   217  	for i := 0; i < b.N; i++ {
   218  		a = a != safeTestBytes(p)
   219  	}
   220  	GloBool = a // Use of benchmark "result" to prevent total dead code elimination.
   221  }