github.com/songzhibin97/gkit@v1.2.13/structure/lscq/bench_test.go (about) 1 // Copyright 2021 ByteDance Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package lscq 16 17 import ( 18 "github.com/songzhibin97/gkit/internal/benchmark/linkedq" 19 "github.com/songzhibin97/gkit/internal/benchmark/msq" 20 "github.com/songzhibin97/gkit/sys/fastrand" 21 "sync/atomic" 22 "testing" 23 ) 24 25 type uint64queue interface { 26 Enqueue(uint64) bool 27 Dequeue() (uint64, bool) 28 } 29 30 type benchTask struct { 31 name string 32 New func() uint64queue 33 } 34 35 type faa int64 36 37 func (data *faa) Enqueue(_ uint64) bool { 38 atomic.AddInt64((*int64)(data), 1) 39 return true 40 } 41 42 func (data *faa) Dequeue() (uint64, bool) { 43 atomic.AddInt64((*int64)(data), -1) 44 return 0, false 45 } 46 47 func BenchmarkDefault(b *testing.B) { 48 all := []benchTask{{ 49 name: "LSCQ", New: func() uint64queue { 50 return NewUint64() 51 }}} 52 all = append(all, benchTask{ 53 name: "LinkedQueue", 54 New: func() uint64queue { 55 return linkedq.New() 56 }, 57 }) 58 all = append(all, benchTask{ 59 name: "MSQueue", 60 New: func() uint64queue { 61 return msq.New() 62 }, 63 }) 64 // all = append(all, benchTask{ 65 // name: "FAA", 66 // New: func() uint64queue { 67 // return new(faa) 68 // }, 69 // }) 70 // all = append(all, benchTask{ 71 // name: "channel", 72 // New: func() uint64queue { 73 // return newChannelQ(scqsize) 74 // }, 75 // }) 76 benchEnqueueOnly(b, all) 77 benchDequeueOnlyEmpty(b, all) 78 benchPair(b, all) 79 bench50Enqueue50Dequeue(b, all) 80 bench30Enqueue70Dequeue(b, all) 81 bench70Enqueue30Dequeue(b, all) 82 } 83 84 func reportalloc(b *testing.B) { 85 // b.SetBytes(8) 86 // b.ReportAllocs() 87 } 88 89 func benchPair(b *testing.B, benchTasks []benchTask) { 90 for _, v := range benchTasks { 91 b.Run("Pair/"+v.name, func(b *testing.B) { 92 q := v.New() 93 reportalloc(b) 94 b.ResetTimer() 95 b.RunParallel(func(pb *testing.PB) { 96 for pb.Next() { 97 q.Enqueue(uint64(fastrand.Uint32())) 98 q.Dequeue() 99 } 100 }) 101 }) 102 } 103 } 104 105 func bench50Enqueue50Dequeue(b *testing.B, benchTasks []benchTask) { 106 for _, v := range benchTasks { 107 b.Run("50Enqueue50Dequeue/"+v.name, func(b *testing.B) { 108 q := v.New() 109 b.ResetTimer() 110 reportalloc(b) 111 b.RunParallel(func(pb *testing.PB) { 112 for pb.Next() { 113 if fastrand.Uint32n(2) == 0 { 114 q.Enqueue(uint64(fastrand.Uint32())) 115 } else { 116 q.Dequeue() 117 } 118 } 119 }) 120 }) 121 } 122 } 123 124 func bench70Enqueue30Dequeue(b *testing.B, benchTasks []benchTask) { 125 for _, v := range benchTasks { 126 b.Run("70Enqueue30Dequeue/"+v.name, func(b *testing.B) { 127 q := v.New() 128 reportalloc(b) 129 b.ResetTimer() 130 b.RunParallel(func(pb *testing.PB) { 131 for pb.Next() { 132 if fastrand.Uint32n(10) > 2 { 133 q.Enqueue(uint64(fastrand.Uint32())) 134 } else { 135 q.Dequeue() 136 } 137 } 138 }) 139 }) 140 } 141 } 142 143 func bench30Enqueue70Dequeue(b *testing.B, benchTasks []benchTask) { 144 for _, v := range benchTasks { 145 b.Run("30Enqueue70Dequeue/"+v.name, func(b *testing.B) { 146 q := v.New() 147 reportalloc(b) 148 b.ResetTimer() 149 b.RunParallel(func(pb *testing.PB) { 150 for pb.Next() { 151 if fastrand.Uint32n(10) <= 2 { 152 q.Enqueue(uint64(fastrand.Uint32())) 153 } else { 154 q.Dequeue() 155 } 156 } 157 }) 158 }) 159 } 160 } 161 162 func benchEnqueueOnly(b *testing.B, benchTasks []benchTask) { 163 for _, v := range benchTasks { 164 b.Run("EnqueueOnly/"+v.name, func(b *testing.B) { 165 q := v.New() 166 reportalloc(b) 167 b.ResetTimer() 168 b.RunParallel(func(pb *testing.PB) { 169 for pb.Next() { 170 q.Enqueue(uint64(fastrand.Uint32())) 171 } 172 }) 173 }) 174 } 175 } 176 177 func benchDequeueOnlyEmpty(b *testing.B, benchTasks []benchTask) { 178 for _, v := range benchTasks { 179 b.Run("DequeueOnlyEmpty/"+v.name, func(b *testing.B) { 180 q := v.New() 181 reportalloc(b) 182 b.ResetTimer() 183 b.RunParallel(func(pb *testing.PB) { 184 for pb.Next() { 185 q.Dequeue() 186 } 187 }) 188 }) 189 } 190 }