github.com/randomizedcoder/goTrackRTP@v0.0.2/trackRTP_math_test.go (about) 1 package goTrackRTP 2 3 import ( 4 "reflect" 5 "testing" 6 _ "unsafe" 7 ) 8 9 // https://github.com/randomizedcoder/goTrackRTP/ 10 11 // See also: https://dave.cheney.net/2019/05/07/prefer-table-driven-tests 12 13 func BenchmarkIsLess(b *testing.B) { 14 for i := 0; i < b.N; i++ { 15 if i%2 == 0 { 16 isLess(uint16(i), uint16(i+5)) 17 } else { 18 isLess(uint16(i), uint16(i-5)) 19 } 20 } 21 } 22 23 func BenchmarkIsGreaterBranchless(b *testing.B) { 24 for i := 0; i < b.N; i++ { 25 if i%2 == 0 { 26 isLessBranchless(uint16(i), uint16(i+5)) 27 } else { 28 isLessBranchless(uint16(i), uint16(i-5)) 29 } 30 } 31 } 32 33 func BenchmarkIsGreaterBranch(b *testing.B) { 34 for i := 0; i < b.N; i++ { 35 if i%2 == 0 { 36 isLessBranch(uint16(i), uint16(i+5)) 37 } else { 38 isLessBranch(uint16(i), uint16(i-5)) 39 } 40 } 41 } 42 43 func TestIsLess(t *testing.T) { 44 type test struct { 45 m uint16 46 seq uint16 47 want bool 48 } 49 50 tests := []test{ 51 // obvious 52 {0, 1, false}, 53 {1, 0, true}, 54 {100, 101, false}, 55 {101, 100, true}, 56 {65535, 65534, true}, 57 // less obvious 58 {0, 65535, true}, 59 {65535, 0, false}, 60 {1, 65535, true}, 61 {65535, 1, false}, 62 {10, 65535, true}, 63 {65535, 10, false}, 64 {100, 65535, true}, 65 {65535, 100, false}, 66 {0, maxUint16 / 2, false}, 67 {maxUint16 / 2, 0, true}, 68 // more for good measure 69 {0, 65000, true}, 70 {65000, 0, false}, 71 {1, 65000, true}, 72 {65000, 1, false}, 73 {10, 65000, true}, 74 {65000, 10, false}, 75 {100, 65000, true}, 76 {65000, 100, false}, 77 // same 78 {0, 0, false}, 79 {1000, 1000, false}, 80 {maxUint16 / 2, maxUint16 / 2, false}, 81 {65535, 65535, false}, 82 } 83 84 for i, tc := range tests { 85 86 t.Logf("%s i:%d, m:%v, seq:%v\n", t.Name(), i, tc.m, tc.seq) 87 88 got := isLess(tc.seq, tc.m) 89 90 if !reflect.DeepEqual(tc.want, got) { 91 t.Fatalf("test: %d, expected: %v, got: %v", i, tc.want, got) 92 } 93 } 94 } 95 96 func TestIsLessBranchless(t *testing.T) { 97 type test struct { 98 m uint16 99 seq uint16 100 want bool 101 } 102 103 tests := []test{ 104 // obvious 105 {0, 1, false}, 106 {1, 0, true}, 107 {100, 101, false}, 108 {101, 100, true}, 109 {65535, 65534, true}, 110 // less obvious 111 {0, 65535, true}, 112 {65535, 0, false}, 113 {1, 65535, true}, 114 {65535, 1, false}, 115 {10, 65535, true}, 116 {65535, 10, false}, 117 {100, 65535, true}, 118 {65535, 100, false}, 119 {0, maxUint16 / 2, false}, 120 {maxUint16 / 2, 0, true}, 121 // more for good measure 122 {0, 65000, true}, 123 {65000, 0, false}, 124 {1, 65000, true}, 125 {65000, 1, false}, 126 {10, 65000, true}, 127 {65000, 10, false}, 128 {100, 65000, true}, 129 {65000, 100, false}, 130 // same 131 {0, 0, false}, 132 {1000, 1000, false}, 133 {maxUint16 / 2, maxUint16 / 2, false}, 134 {65535, 65535, false}, 135 } 136 137 for i, tc := range tests { 138 139 t.Logf("%s i:%d, m:%v, seq:%v\n", t.Name(), i, tc.m, tc.seq) 140 141 got := isLessBranchless(tc.seq, tc.m) 142 143 if !reflect.DeepEqual(tc.want, got) { 144 t.Fatalf("test: %d, expected: %v, got: %v", i, tc.want, got) 145 } 146 } 147 } 148 149 func TestIsLessBranch(t *testing.T) { 150 type test struct { 151 m uint16 152 seq uint16 153 want bool 154 } 155 156 tests := []test{ 157 // obvious 158 {0, 1, false}, 159 {1, 0, true}, 160 {100, 101, false}, 161 {101, 100, true}, 162 {65535, 65534, true}, 163 // less obvious 164 {0, 65535, true}, 165 {65535, 0, false}, 166 {1, 65535, true}, 167 {65535, 1, false}, 168 {10, 65535, true}, 169 {65535, 10, false}, 170 {100, 65535, true}, 171 {65535, 100, false}, 172 {0, maxUint16 / 2, false}, 173 {maxUint16 / 2, 0, true}, 174 // more for good measure 175 {0, 65000, true}, 176 {65000, 0, false}, 177 {1, 65000, true}, 178 {65000, 1, false}, 179 {10, 65000, true}, 180 {65000, 10, false}, 181 {100, 65000, true}, 182 {65000, 100, false}, 183 // same 184 {0, 0, false}, 185 {1000, 1000, false}, 186 {maxUint16 / 2, maxUint16 / 2, false}, 187 {65535, 65535, false}, 188 } 189 190 for i, tc := range tests { 191 192 t.Logf("%s i:%d, m:%v, seq:%v\n", t.Name(), i, tc.m, tc.seq) 193 194 got := isLessBranch(tc.seq, tc.m) 195 196 if !reflect.DeepEqual(tc.want, got) { 197 t.Fatalf("test: %d, expected: %v, got: %v", i, tc.want, got) 198 } 199 } 200 } 201 202 func TestDiff(t *testing.T) { 203 type test struct { 204 m uint16 205 seq uint16 206 want uint16 207 } 208 209 tests := []test{ 210 {0, 1, 1}, 211 {1, 0, 1}, 212 // wrapping 213 {0, 65535, 1}, 214 {65535, 0, 1}, 215 {1, 65535, 2}, 216 {65535, 1, 2}, 217 {10, 65535, 11}, 218 {65535, 10, 11}, 219 // obvious 220 {0, 1, 1}, 221 {1, 0, 1}, 222 {100, 101, 1}, 223 {101, 100, 1}, 224 {65534, 65535, 1}, 225 {65535, 65534, 1}, 226 {1, 65535, 2}, 227 {10, 65535, 11}, 228 {100, 65535, 101}, 229 {0, maxUint16 / 2, maxUint16 / 2}, 230 {maxUint16 / 2, 0, maxUint16 / 2}, 231 //{0, 65000, 65000}, // fails 232 {1, 65000, 537}, 233 {10, 65000, 546}, 234 {100, 65000, 636}, 235 // // same 236 {0, 0, 0}, 237 {1000, 1000, 0}, 238 {maxUint16 / 2, maxUint16 / 2, 0}, 239 {65535, 65535, 0}, 240 } 241 242 // I was trying to work out a branchless version, but didn't get there yet 243 // can't work out how to iterate function :( 244 // var fns []func(s1, s2 uint16) 245 // fns = append(fns, absoluteDifference) 246 // fns = append(fns, uint16Diff) 247 //fns := []string{"absoluteDifference", "uint16Diff"} 248 //fns := []string{"uint16Diff"} 249 250 for i, tc := range tests { 251 252 //for f, fn := range fns { 253 254 t.Logf("%s i:%d, m:%v, seq:%v, want:%d\n", t.Name(), i, tc.m, tc.seq, tc.want) 255 //t.Logf("%s i:%d, fn:%s, m:%v, seq:%v, want:%d\n", t.Name(), i, fn, tc.m, tc.seq, tc.want) 256 257 //got := fn(tc.m, tc.seq) 258 259 // var got uint16 260 // if f == 1 { 261 // got = absoluteDifference(tc.m, tc.seq) 262 // } else { 263 // got = uint16Diff(tc.m, tc.seq) 264 // } 265 got := uint16Diff(tc.m, tc.seq) 266 267 t.Logf("%s i:%d, m:%v, seq:%v, want:%d, got:%d, deepequal:%t\n", t.Name(), i, tc.m, tc.seq, tc.want, got, reflect.DeepEqual(tc.want, got)) 268 269 if !reflect.DeepEqual(tc.want, got) { 270 t.Fatalf("test: %d, expected: %v, got: %v", i, tc.want, got) 271 } 272 //} 273 } 274 }