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