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.
13 var compareTests = []struct {
17 {[]byte(""), []byte(""), 0},
18 {[]byte("a"), []byte(""), 1},
19 {[]byte(""), []byte("a"), -1},
20 {[]byte("abc"), []byte("abc"), 0},
21 {[]byte("abd"), []byte("abc"), 1},
22 {[]byte("abc"), []byte("abd"), -1},
23 {[]byte("ab"), []byte("abc"), -1},
24 {[]byte("abc"), []byte("ab"), 1},
25 {[]byte("x"), []byte("ab"), 1},
26 {[]byte("ab"), []byte("x"), -1},
27 {[]byte("x"), []byte("a"), 1},
28 {[]byte("b"), []byte("x"), -1},
29 // test runtime·memeq's chunked implementation
30 {[]byte("abcdefgh"), []byte("abcdefgh"), 0},
31 {[]byte("abcdefghi"), []byte("abcdefghi"), 0},
32 {[]byte("abcdefghi"), []byte("abcdefghj"), -1},
33 {[]byte("abcdefghj"), []byte("abcdefghi"), 1},
38 {[]byte("a"), nil, 1},
39 {nil, []byte("a"), -1},
42 func TestCompare(t *testing.T) {
43 for _, tt := range compareTests {
45 buffer := make([]byte, len(tt.b)+numShifts)
46 // vary the input alignment of tt.b
47 for offset := 0; offset <= numShifts; offset++ {
48 shiftedB := buffer[offset : len(tt.b)+offset]
50 cmp := Compare(tt.a, shiftedB)
52 t.Errorf(`Compare(%q, %q), offset %d = %v; want %v`, tt.a, tt.b, offset, cmp, tt.i)
58 func TestCompareIdenticalSlice(t *testing.T) {
59 var b = []byte("Hello Gophers!")
60 if Compare(b, b) != 0 {
63 if Compare(b, b[:1]) != 1 {
64 t.Error("b > b[:1] failed")
68 func TestCompareBytes(t *testing.T) {
69 lengths := make([]int, 0) // lengths to test in ascending order
70 for i := 0; i <= 128; i++ {
71 lengths = append(lengths, i)
73 lengths = append(lengths, 256, 512, 1024, 1333, 4095, 4096, 4097)
76 lengths = append(lengths, 65535, 65536, 65537, 99999)
79 n := lengths[len(lengths)-1]
80 a := make([]byte, n+1)
81 b := make([]byte, n+1)
82 for _, len := range lengths {
83 // randomish but deterministic data. No 0 or 255.
84 for i := 0; i < len; i++ {
85 a[i] = byte(1 + 31*i%254)
86 b[i] = byte(1 + 31*i%254)
88 // data past the end is different
89 for i := len; i <= n; i++ {
93 cmp := Compare(a[:len], b[:len])
95 t.Errorf(`CompareIdentical(%d) = %d`, len, cmp)
98 cmp = Compare(a[:len-1], b[:len])
100 t.Errorf(`CompareAshorter(%d) = %d`, len, cmp)
102 cmp = Compare(a[:len], b[:len-1])
104 t.Errorf(`CompareBshorter(%d) = %d`, len, cmp)
107 for k := 0; k < len; k++ {
109 cmp = Compare(a[:len], b[:len])
111 t.Errorf(`CompareAbigger(%d,%d) = %d`, len, k, cmp)
114 cmp = Compare(a[:len], b[:len])
116 t.Errorf(`CompareBbigger(%d,%d) = %d`, len, k, cmp)
123 func TestEndianBaseCompare(t *testing.T) {
124 // This test compares byte slices that are almost identical, except one
125 // difference that for some j, a[j]>b[j] and a[j+1]<b[j+1]. If the implementation
126 // compares large chunks with wrong endianness, it gets wrong result.
127 // no vector register is larger than 512 bytes for now
128 const maxLength = 512
129 a := make([]byte, maxLength)
130 b := make([]byte, maxLength)
131 // randomish but deterministic data. No 0 or 255.
132 for i := 0; i < maxLength; i++ {
133 a[i] = byte(1 + 31*i%254)
134 b[i] = byte(1 + 31*i%254)
136 for i := 2; i <= maxLength; i <<= 1 {
137 for j := 0; j < i-1; j++ {
140 cmp := Compare(a[:i], b[:i])
142 t.Errorf(`CompareBbigger(%d,%d) = %d`, i, j, cmp)
146 cmp = Compare(a[:i], b[:i])
148 t.Errorf(`CompareAbigger(%d,%d) = %d`, i, j, cmp)
156 func BenchmarkCompareBytesEqual(b *testing.B) {
157 b1 := []byte("Hello Gophers!")
158 b2 := []byte("Hello Gophers!")
159 for i := 0; i < b.N; i++ {
160 if Compare(b1, b2) != 0 {
166 func BenchmarkCompareBytesToNil(b *testing.B) {
167 b1 := []byte("Hello Gophers!")
169 for i := 0; i < b.N; i++ {
170 if Compare(b1, b2) != 1 {
171 b.Fatal("b1 > b2 failed")
176 func BenchmarkCompareBytesEmpty(b *testing.B) {
179 for i := 0; i < b.N; i++ {
180 if Compare(b1, b2) != 0 {
186 func BenchmarkCompareBytesIdentical(b *testing.B) {
187 b1 := []byte("Hello Gophers!")
189 for i := 0; i < b.N; i++ {
190 if Compare(b1, b2) != 0 {
196 func BenchmarkCompareBytesSameLength(b *testing.B) {
197 b1 := []byte("Hello Gophers!")
198 b2 := []byte("Hello, Gophers")
199 for i := 0; i < b.N; i++ {
200 if Compare(b1, b2) != -1 {
201 b.Fatal("b1 < b2 failed")
206 func BenchmarkCompareBytesDifferentLength(b *testing.B) {
207 b1 := []byte("Hello Gophers!")
208 b2 := []byte("Hello, Gophers!")
209 for i := 0; i < b.N; i++ {
210 if Compare(b1, b2) != -1 {
211 b.Fatal("b1 < b2 failed")
216 func benchmarkCompareBytesBigUnaligned(b *testing.B, offset int) {
218 b1 := make([]byte, 0, 1<<20)
219 for len(b1) < 1<<20 {
220 b1 = append(b1, "Hello Gophers!"...)
222 b2 := append([]byte("12345678")[:offset], b1...)
224 for j := 0; j < b.N; j++ {
225 if Compare(b1, b2[offset:]) != 0 {
229 b.SetBytes(int64(len(b1)))
232 func BenchmarkCompareBytesBigUnaligned(b *testing.B) {
233 for i := 1; i < 8; i++ {
234 b.Run(fmt.Sprintf("offset=%d", i), func(b *testing.B) {
235 benchmarkCompareBytesBigUnaligned(b, i)
240 func benchmarkCompareBytesBigBothUnaligned(b *testing.B, offset int) {
242 pattern := []byte("Hello Gophers!")
243 b1 := make([]byte, 0, 1<<20+len(pattern))
244 for len(b1) < 1<<20 {
245 b1 = append(b1, pattern...)
247 b2 := make([]byte, len(b1))
250 for j := 0; j < b.N; j++ {
251 if Compare(b1[offset:], b2[offset:]) != 0 {
255 b.SetBytes(int64(len(b1[offset:])))
258 func BenchmarkCompareBytesBigBothUnaligned(b *testing.B) {
259 for i := 0; i < 8; i++ {
260 b.Run(fmt.Sprintf("offset=%d", i), func(b *testing.B) {
261 benchmarkCompareBytesBigBothUnaligned(b, i)
266 func BenchmarkCompareBytesBig(b *testing.B) {
268 b1 := make([]byte, 0, 1<<20)
269 for len(b1) < 1<<20 {
270 b1 = append(b1, "Hello Gophers!"...)
272 b2 := append([]byte{}, b1...)
274 for i := 0; i < b.N; i++ {
275 if Compare(b1, b2) != 0 {
279 b.SetBytes(int64(len(b1)))
282 func BenchmarkCompareBytesBigIdentical(b *testing.B) {
284 b1 := make([]byte, 0, 1<<20)
285 for len(b1) < 1<<20 {
286 b1 = append(b1, "Hello Gophers!"...)
290 for i := 0; i < b.N; i++ {
291 if Compare(b1, b2) != 0 {
295 b.SetBytes(int64(len(b1)))