github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/common/bitutil/bitutil_test.go (about)

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