github.com/sunvim/utils@v0.1.0/linear_ac/linear_ac_bench_test.go (about) 1 // reference to 2 // https://github.com/crazybie/linear_ac 3 4 package linear_ac 5 6 import ( 7 "fmt" 8 "runtime" 9 "sync" 10 "sync/atomic" 11 "testing" 12 "time" 13 ) 14 15 var ( 16 totalTasks = 100000 17 totalGoroutines = 500 18 busyGoroutineId = 1 19 busyGoroutineLoop = 1000 20 ) 21 22 var largeConfigData []*PbDataEx 23 24 func makeGlobalData() { 25 if largeConfigData == nil { 26 largeConfigData = make([]*PbDataEx, 100000) 27 for i := range largeConfigData { 28 largeConfigData[i] = makeData(i) 29 } 30 } 31 } 32 33 func Dispatch(genTasks func(chan func(int))) { 34 35 wait := sync.WaitGroup{} 36 wait.Add(totalGoroutines) 37 queue := make(chan func(int), totalGoroutines) 38 maxLatency, totalLatency := int64(0), int64(0) 39 cnt := int64(0) 40 41 for i := 0; i < totalGoroutines; i++ { 42 go func(routineId int) { 43 for task := range queue { 44 45 s := time.Now().UnixNano() 46 task(routineId) 47 elapsed := time.Now().UnixNano() - s 48 49 atomic.AddInt64(&totalLatency, elapsed) 50 atomic.AddInt64(&cnt, 1) 51 if elapsed > atomic.LoadInt64(&maxLatency) { 52 atomic.StoreInt64(&maxLatency, elapsed) 53 } 54 } 55 wait.Done() 56 }(i) 57 } 58 59 genTasks(queue) 60 close(queue) 61 wait.Wait() 62 63 fmt.Printf(">> Latency: max=%vms, avg=%vms.\n", maxLatency/1000/1000, totalLatency/cnt/1000/1000) 64 } 65 66 func Benchmark_LinearAc(t *testing.B) { 67 DbgMode = false 68 chunkPool.reserve(1600) 69 makeGlobalData() 70 runtime.GC() 71 t.StartTimer() 72 73 Dispatch(func(queue chan func(int)) { 74 for i := 0; i < totalTasks; i++ { 75 queue <- func(routine int) { 76 77 subLoop := 1 78 if routine == busyGoroutineId { 79 subLoop = busyGoroutineLoop 80 } 81 82 for n := 0; n < subLoop; n++ { 83 ac := BindNew() 84 _ = makeDataAc(n) 85 ac.Release() 86 } 87 } 88 } 89 }) 90 91 acPool.clear() 92 chunkPool.clear() 93 } 94 95 func Benchmark_buildInAc(t *testing.B) { 96 makeGlobalData() 97 runtime.GC() 98 t.StartTimer() 99 100 Dispatch(func(c chan func(int)) { 101 for i := 0; i < totalTasks; i++ { 102 c <- func(routine int) { 103 104 subLoop := 1 105 if routine == busyGoroutineId { 106 subLoop = busyGoroutineLoop 107 } 108 109 for n := 0; n < subLoop; n++ { 110 _ = makeData(n) 111 } 112 } 113 } 114 }) 115 } 116 117 type PbItemEx struct { 118 Id1 *int 119 Id2 *int 120 Id3 *int 121 Id4 *int 122 Id5 *int 123 Id6 *int 124 Id7 *int 125 Id8 *int 126 Id9 *int 127 Id10 *int 128 Price *int 129 Class *int 130 Name1 *string 131 Active *bool 132 EnumVal *EnumA 133 } 134 135 type PbDataEx struct { 136 Age1 *int 137 Age2 *int 138 Age3 *int 139 Age4 *int 140 Age5 *int 141 Age6 *int 142 Age7 *int 143 Age8 *int 144 Age9 *int 145 Age10 *int 146 Items1 []*PbItemEx 147 Items2 []*PbItemEx 148 Items3 []*PbItemEx 149 Items4 []*PbItemEx 150 Items5 []*PbItemEx 151 Items6 []*PbItemEx 152 Items7 []*PbItemEx 153 Items8 []*PbItemEx 154 Items9 []*PbItemEx 155 InUse1 *PbItemEx 156 InUse2 *PbItemEx 157 InUse3 *PbItemEx 158 InUse4 *PbItemEx 159 InUse5 *PbItemEx 160 InUse6 *PbItemEx 161 InUse7 *PbItemEx 162 InUse8 *PbItemEx 163 InUse9 *PbItemEx 164 InUse10 *PbItemEx 165 } 166 167 var newInt = func(v int) *int { return &v } 168 var newStr = func(v string) *string { return &v } 169 var newBool = func(v bool) *bool { return &v } 170 var newEnum = func(v EnumA) *EnumA { return &v } 171 172 var makeItem = func(j int) *PbItemEx { 173 item := &PbItemEx{ 174 Id1: newInt(2 + j), 175 Id2: newInt(2 + j), 176 Id3: newInt(2 + j), 177 Id4: newInt(2 + j), 178 Id5: newInt(2 + j), 179 Id6: newInt(2 + j), 180 Id7: newInt(2 + j), 181 Id8: newInt(2 + j), 182 Id9: newInt(2 + j), 183 Id10: newInt(2 + j), 184 Price: newInt(100 + j), 185 Class: newInt(3 + j), 186 Name1: newStr("name"), 187 Active: newBool(true), 188 EnumVal: newEnum(EnumVal2), 189 } 190 return item 191 } 192 193 var makeItemAc = func(j int, ac *Allocator) *PbItemEx { 194 return ac.NewCopy(&PbItemEx{ 195 Id1: ac.Int(2 + j), 196 Id2: ac.Int(2 + j), 197 Id3: ac.Int(2 + j), 198 Id4: ac.Int(2 + j), 199 Id5: ac.Int(2 + j), 200 Id6: ac.Int(2 + j), 201 Id7: ac.Int(2 + j), 202 Id8: ac.Int(2 + j), 203 Id9: ac.Int(2 + j), 204 Id10: ac.Int(2 + j), 205 Price: ac.Int(100 + j), 206 Class: ac.Int(3 + j), 207 Name1: ac.String("name"), 208 Active: ac.Bool(true), 209 EnumVal: ac.Enum(EnumVal2).(*EnumA), 210 }).(*PbItemEx) 211 } 212 213 var itemLoop = 10 214 215 func makeData(i int) *PbDataEx { 216 d := new(PbDataEx) 217 d.Age1 = newInt(11 + i) 218 d.Age2 = newInt(11 + i) 219 d.Age3 = newInt(11 + i) 220 d.Age4 = newInt(11 + i) 221 d.Age5 = newInt(11 + i) 222 d.Age6 = newInt(11 + i) 223 d.Age7 = newInt(11 + i) 224 d.Age8 = newInt(11 + i) 225 d.Age9 = newInt(11 + i) 226 d.Age10 = newInt(11 + i) 227 228 d.InUse1 = makeItem(i) 229 d.InUse2 = makeItem(i) 230 d.InUse3 = makeItem(i) 231 d.InUse4 = makeItem(i) 232 d.InUse5 = makeItem(i) 233 d.InUse6 = makeItem(i) 234 d.InUse7 = makeItem(i) 235 d.InUse8 = makeItem(i) 236 d.InUse9 = makeItem(i) 237 d.InUse10 = makeItem(i) 238 239 for j := 0; j < itemLoop; j++ { 240 d.Items1 = append(d.Items1, makeItem(j)) 241 } 242 for j := 0; j < itemLoop; j++ { 243 d.Items2 = append(d.Items2, makeItem(j)) 244 } 245 for j := 0; j < itemLoop; j++ { 246 d.Items3 = append(d.Items3, makeItem(j)) 247 } 248 for j := 0; j < itemLoop; j++ { 249 d.Items4 = append(d.Items4, makeItem(j)) 250 } 251 for j := 0; j < itemLoop; j++ { 252 d.Items5 = append(d.Items5, makeItem(j)) 253 } 254 for j := 0; j < itemLoop; j++ { 255 d.Items6 = append(d.Items6, makeItem(j)) 256 } 257 for j := 0; j < itemLoop; j++ { 258 d.Items7 = append(d.Items7, makeItem(j)) 259 } 260 for j := 0; j < itemLoop; j++ { 261 d.Items8 = append(d.Items8, makeItem(j)) 262 } 263 for j := 0; j < itemLoop; j++ { 264 d.Items9 = append(d.Items9, makeItem(j)) 265 } 266 return d 267 } 268 269 func makeDataAc(i int) *PbDataEx { 270 ac := Get() 271 272 var d *PbDataEx 273 ac.New(&d) 274 d.Age1 = ac.Int(11 + i) 275 d.Age2 = ac.Int(11 + i) 276 d.Age3 = ac.Int(11 + i) 277 d.Age4 = ac.Int(11 + i) 278 d.Age5 = ac.Int(11 + i) 279 d.Age6 = ac.Int(11 + i) 280 d.Age7 = ac.Int(11 + i) 281 d.Age8 = ac.Int(11 + i) 282 d.Age9 = ac.Int(11 + i) 283 d.Age10 = ac.Int(11 + i) 284 285 d.InUse1 = makeItemAc(i, ac) 286 d.InUse2 = makeItemAc(i, ac) 287 d.InUse3 = makeItemAc(i, ac) 288 d.InUse4 = makeItemAc(i, ac) 289 d.InUse5 = makeItemAc(i, ac) 290 d.InUse6 = makeItemAc(i, ac) 291 d.InUse7 = makeItemAc(i, ac) 292 d.InUse8 = makeItemAc(i, ac) 293 d.InUse9 = makeItemAc(i, ac) 294 d.InUse10 = makeItemAc(i, ac) 295 296 for j := 0; j < itemLoop; j++ { 297 ac.SliceAppend(&d.Items1, makeItemAc(j, ac)) 298 } 299 for j := 0; j < itemLoop; j++ { 300 ac.SliceAppend(&d.Items2, makeItemAc(j, ac)) 301 } 302 for j := 0; j < itemLoop; j++ { 303 ac.SliceAppend(&d.Items3, makeItemAc(j, ac)) 304 } 305 for j := 0; j < itemLoop; j++ { 306 ac.SliceAppend(&d.Items4, makeItemAc(j, ac)) 307 } 308 for j := 0; j < itemLoop; j++ { 309 ac.SliceAppend(&d.Items5, makeItemAc(j, ac)) 310 } 311 for j := 0; j < itemLoop; j++ { 312 ac.SliceAppend(&d.Items6, makeItemAc(j, ac)) 313 } 314 for j := 0; j < itemLoop; j++ { 315 ac.SliceAppend(&d.Items7, makeItemAc(j, ac)) 316 } 317 for j := 0; j < itemLoop; j++ { 318 ac.SliceAppend(&d.Items8, makeItemAc(j, ac)) 319 } 320 for j := 0; j < itemLoop; j++ { 321 ac.SliceAppend(&d.Items9, makeItemAc(j, ac)) 322 } 323 return d 324 }