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