github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/collection/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 "sync/atomic" 19 "testing" 20 21 "github.com/bytedance/gopkg/internal/benchmark/linkedq" 22 "github.com/bytedance/gopkg/internal/benchmark/msq" 23 "github.com/bytedance/gopkg/lang/fastrand" 24 ) 25 26 type uint64queue interface { 27 Enqueue(uint64) bool 28 Dequeue() (uint64, bool) 29 } 30 31 type benchTask struct { 32 name string 33 New func() uint64queue 34 } 35 36 type faa int64 37 38 func (data *faa) Enqueue(_ uint64) bool { 39 atomic.AddInt64((*int64)(data), 1) 40 return true 41 } 42 43 func (data *faa) Dequeue() (uint64, bool) { 44 atomic.AddInt64((*int64)(data), -1) 45 return 0, false 46 } 47 48 func BenchmarkDefault(b *testing.B) { 49 all := []benchTask{{ 50 name: "LSCQ", New: func() uint64queue { 51 return NewUint64() 52 }}} 53 all = append(all, benchTask{ 54 name: "LinkedQueue", 55 New: func() uint64queue { 56 return linkedq.New() 57 }, 58 }) 59 all = append(all, benchTask{ 60 name: "MSQueue", 61 New: func() uint64queue { 62 return msq.New() 63 }, 64 }) 65 // all = append(all, benchTask{ 66 // name: "FAA", 67 // New: func() uint64queue { 68 // return new(faa) 69 // }, 70 // }) 71 // all = append(all, benchTask{ 72 // name: "channel", 73 // New: func() uint64queue { 74 // return newChannelQ(scqsize) 75 // }, 76 // }) 77 benchEnqueueOnly(b, all) 78 benchDequeueOnlyEmpty(b, all) 79 benchPair(b, all) 80 bench50Enqueue50Dequeue(b, all) 81 bench30Enqueue70Dequeue(b, all) 82 bench70Enqueue30Dequeue(b, all) 83 } 84 85 func reportalloc(b *testing.B) { 86 // b.SetBytes(8) 87 // b.ReportAllocs() 88 } 89 90 func benchPair(b *testing.B, benchTasks []benchTask) { 91 for _, v := range benchTasks { 92 b.Run("Pair/"+v.name, func(b *testing.B) { 93 q := v.New() 94 reportalloc(b) 95 b.ResetTimer() 96 b.RunParallel(func(pb *testing.PB) { 97 for pb.Next() { 98 q.Enqueue(uint64(fastrand.Uint32())) 99 q.Dequeue() 100 } 101 }) 102 }) 103 } 104 } 105 106 func bench50Enqueue50Dequeue(b *testing.B, benchTasks []benchTask) { 107 for _, v := range benchTasks { 108 b.Run("50Enqueue50Dequeue/"+v.name, func(b *testing.B) { 109 q := v.New() 110 b.ResetTimer() 111 reportalloc(b) 112 b.RunParallel(func(pb *testing.PB) { 113 for pb.Next() { 114 if fastrand.Uint32n(2) == 0 { 115 q.Enqueue(uint64(fastrand.Uint32())) 116 } else { 117 q.Dequeue() 118 } 119 } 120 }) 121 }) 122 } 123 } 124 125 func bench70Enqueue30Dequeue(b *testing.B, benchTasks []benchTask) { 126 for _, v := range benchTasks { 127 b.Run("70Enqueue30Dequeue/"+v.name, func(b *testing.B) { 128 q := v.New() 129 reportalloc(b) 130 b.ResetTimer() 131 b.RunParallel(func(pb *testing.PB) { 132 for pb.Next() { 133 if fastrand.Uint32n(10) > 2 { 134 q.Enqueue(uint64(fastrand.Uint32())) 135 } else { 136 q.Dequeue() 137 } 138 } 139 }) 140 }) 141 } 142 } 143 144 func bench30Enqueue70Dequeue(b *testing.B, benchTasks []benchTask) { 145 for _, v := range benchTasks { 146 b.Run("30Enqueue70Dequeue/"+v.name, func(b *testing.B) { 147 q := v.New() 148 reportalloc(b) 149 b.ResetTimer() 150 b.RunParallel(func(pb *testing.PB) { 151 for pb.Next() { 152 if fastrand.Uint32n(10) <= 2 { 153 q.Enqueue(uint64(fastrand.Uint32())) 154 } else { 155 q.Dequeue() 156 } 157 } 158 }) 159 }) 160 } 161 } 162 163 func benchEnqueueOnly(b *testing.B, benchTasks []benchTask) { 164 for _, v := range benchTasks { 165 b.Run("EnqueueOnly/"+v.name, func(b *testing.B) { 166 q := v.New() 167 reportalloc(b) 168 b.ResetTimer() 169 b.RunParallel(func(pb *testing.PB) { 170 for pb.Next() { 171 q.Enqueue(uint64(fastrand.Uint32())) 172 } 173 }) 174 }) 175 } 176 } 177 178 func benchDequeueOnlyEmpty(b *testing.B, benchTasks []benchTask) { 179 for _, v := range benchTasks { 180 b.Run("DequeueOnlyEmpty/"+v.name, func(b *testing.B) { 181 q := v.New() 182 reportalloc(b) 183 b.ResetTimer() 184 b.RunParallel(func(pb *testing.PB) { 185 for pb.Next() { 186 q.Dequeue() 187 } 188 }) 189 }) 190 } 191 }