go.uber.org/yarpc@v1.72.1/peer/hashring32/internal/radixsort32/radixsort_test.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package radixsort32 22 23 import ( 24 "testing" 25 26 "github.com/stretchr/testify/assert" 27 ) 28 29 // TestRadixSort tests radix sort correctness 30 func TestRadixSort(t *testing.T) { 31 sorter := makeSorter(16, 100, 15000) 32 // short break 33 testRadixSortReversedSlice(t, sorter, 10) 34 // radix sort with buffers in pool 35 testRadixSortReversedSlice(t, sorter, 300) 36 // radix sort with dynamically allocated buffers 37 testRadixSortReversedSlice(t, sorter, 20000) 38 } 39 40 // TestOptions tests options and fallbacks 41 func TestOptions(t *testing.T) { 42 sorter := makeSorter(3, 500000, 100) 43 assert.Equal(t, uint(8), sorter.radix) 44 assert.Equal(t, 100, sorter.maxLength) 45 assert.Equal(t, 100, sorter.minLength) 46 47 sorter2 := makeSorter(3, -50, 100) 48 assert.Equal(t, 0, sorter2.minLength) 49 assert.Equal(t, 100, sorter2.maxLength) 50 } 51 52 func testRadixSortReversedSlice(t *testing.T, sorter *RadixSorter32, size int) { 53 slice := makeRevertedSlice(size) 54 sorter.Sort(slice) 55 assert.EqualValues(t, makeSortedSlice(size), slice) 56 } 57 58 func makeSorter(radix, minLen, maxLen int) *RadixSorter32 { 59 sorter := New( 60 Radix(radix), 61 MinLen(minLen), 62 MaxLen(maxLen)) 63 return sorter 64 } 65 66 func makeRevertedSlice(size int) []uint32 { 67 a := make([]uint32, size) 68 for i := size - 1; i >= 0; i-- { 69 a[i] = uint32(len(a) - 1 - i) 70 } 71 return a 72 } 73 74 func makeSortedSlice(size int) []uint32 { 75 a := make([]uint32, size) 76 for i := 0; i < len(a); i++ { 77 a[i] = uint32(i) 78 } 79 return a 80 } 81 82 // Benchmarks 83 84 func BenchmarkSortSize150KCompare(b *testing.B) { 85 benchmarkCompareSort(b, 150000) 86 } 87 88 func BenchmarkSortSize150KRadix4(b *testing.B) { 89 benchmarkRadixSort(b, 4, 150000) 90 } 91 92 func BenchmarkSortSize150KRadix8(b *testing.B) { 93 benchmarkRadixSort(b, 8, 150000) 94 } 95 96 func BenchmarkSortSize150KRadix16(b *testing.B) { 97 benchmarkRadixSort(b, 16, 150000) 98 } 99 100 func BenchmarkSortSize15KCompare(b *testing.B) { 101 benchmarkCompareSort(b, 15000) 102 } 103 104 func BenchmarkSortSize15KRadix4(b *testing.B) { 105 benchmarkRadixSort(b, 4, 15000) 106 } 107 108 func BenchmarkSortSize15KRadix8(b *testing.B) { 109 benchmarkRadixSort(b, 8, 15000) 110 } 111 112 func BenchmarkSortSize15KRadix16(b *testing.B) { 113 benchmarkRadixSort(b, 16, 15000) 114 } 115 116 func BenchmarkSortSize1500Compare(b *testing.B) { 117 benchmarkCompareSort(b, 1500) 118 } 119 120 func BenchmarkSortSize1500Radix4(b *testing.B) { 121 benchmarkRadixSort(b, 4, 1500) 122 } 123 124 func BenchmarkSortSize1500Radix8(b *testing.B) { 125 benchmarkRadixSort(b, 8, 1500) 126 } 127 128 func BenchmarkSortSize15000KRadix16(b *testing.B) { 129 benchmarkRadixSort(b, 16, 1500) 130 } 131 132 const par = 8 133 134 func benchmarkRadixSort(b *testing.B, radix, size int) { 135 sorter := makeSorter(radix, 0, size) 136 b.SetParallelism(par) 137 b.ResetTimer() 138 139 b.RunParallel(func(pb *testing.PB) { 140 for pb.Next() { 141 sorter.Sort(makeRevertedSlice(size)) 142 } 143 }) 144 } 145 146 func benchmarkCompareSort(b *testing.B, size int) { 147 sorter := makeSorter(8, size, size) 148 b.SetParallelism(par) 149 b.ResetTimer() 150 151 b.RunParallel(func(pb *testing.PB) { 152 for pb.Next() { 153 sorter.Sort(makeRevertedSlice(size)) 154 } 155 }) 156 }