github.com/andy2046/gopie@v0.7.0/pkg/multilane/multilane_test.go (about) 1 package multilane_test 2 3 import ( 4 . "github.com/andy2046/gopie/pkg/multilane" 5 "go.uber.org/goleak" 6 "runtime" 7 "sync" 8 "testing" 9 "time" 10 ) 11 12 var config = Config{ 13 LaneWidth: 8, 14 QueueSize: 1024, 15 } 16 17 func BenchmarkMultiLane_Blocking(b *testing.B) { 18 var ( 19 m = New(config) 20 wgPut, wgGet sync.WaitGroup 21 concurrentGet, concurrentPut = 8, 8 22 ) 23 wgPut.Add(concurrentPut) 24 wgGet.Add(concurrentGet) 25 type T struct { 26 i int 27 } 28 var v = T{5} 29 b.ResetTimer() 30 for c := 0; c < concurrentPut; c++ { 31 go func(n int) { 32 // runtime.LockOSThread() 33 for i := 0; i < n; i++ { 34 m.Put(&v) 35 } 36 wgPut.Done() 37 }(b.N/concurrentPut + 1) 38 } 39 for c := 0; c < concurrentGet; c++ { 40 go func(n int) { 41 // runtime.LockOSThread() 42 var v *T 43 for i := 0; m.Get(&v); i++ { 44 _ = *v 45 } 46 wgGet.Done() 47 }(b.N/concurrentGet + 1) 48 } 49 50 wgPut.Wait() 51 m.Close() 52 wgGet.Wait() 53 } 54 55 func BenchmarkMultiLane_BlockingLane(b *testing.B) { 56 var ( 57 m = New(config) 58 wgPut, wgGet sync.WaitGroup 59 concurrentGet, concurrentPut = 8, 8 60 ) 61 wgPut.Add(concurrentPut) 62 wgGet.Add(concurrentGet) 63 type T struct { 64 i int 65 } 66 var v = T{5} 67 b.ResetTimer() 68 for c := 0; c < concurrentPut; c++ { 69 go func(n int, lane uint32) { 70 // runtime.LockOSThread() 71 for i := 0; i < n; i++ { 72 m.PutLane(lane, &v) 73 } 74 wgPut.Done() 75 }(b.N/concurrentPut+1, uint32(c)) 76 } 77 for c := 0; c < concurrentGet; c++ { 78 go func(n int, lane uint32) { 79 // runtime.LockOSThread() 80 var v *T 81 for i := 0; m.GetLane(lane, &v); i++ { 82 _ = *v 83 } 84 wgGet.Done() 85 }(b.N/concurrentGet+1, uint32(c)) 86 } 87 88 wgPut.Wait() 89 m.Close() 90 wgGet.Wait() 91 } 92 93 func BenchmarkMultiLane_Blocking2(b *testing.B) { 94 var ( 95 m = New(config) 96 wgPut, wgGet sync.WaitGroup 97 concurrentGet, concurrentPut = 8, 8 98 ) 99 wgPut.Add(concurrentPut) 100 wgGet.Add(concurrentGet) 101 type T struct { 102 i int 103 } 104 p := runtime.GOMAXPROCS(concurrentGet + concurrentPut) 105 var v = T{5} 106 b.ResetTimer() 107 for c := 0; c < concurrentPut; c++ { 108 go func(n int) { 109 for i := 0; i < n; i++ { 110 m.Put(&v) 111 } 112 wgPut.Done() 113 }(b.N/concurrentPut + 1) 114 } 115 for c := 0; c < concurrentGet; c++ { 116 go func(n int) { 117 var v *T 118 for i := 0; m.Get(&v); i++ { 119 _ = *v 120 } 121 wgGet.Done() 122 }(b.N/concurrentGet + 1) 123 } 124 125 wgPut.Wait() 126 m.Close() 127 wgGet.Wait() 128 runtime.GOMAXPROCS(p) 129 } 130 131 func BenchmarkMultiLane_BlockingLane2(b *testing.B) { 132 var ( 133 m = New(config) 134 wgPut, wgGet sync.WaitGroup 135 concurrentGet, concurrentPut = 8, 8 136 ) 137 wgPut.Add(concurrentPut) 138 wgGet.Add(concurrentGet) 139 type T struct { 140 i int 141 } 142 p := runtime.GOMAXPROCS(concurrentGet + concurrentPut) 143 var v = T{5} 144 b.ResetTimer() 145 for c := 0; c < concurrentPut; c++ { 146 go func(n int, lane uint32) { 147 for i := 0; i < n; i++ { 148 m.PutLane(lane, &v) 149 } 150 wgPut.Done() 151 }(b.N/concurrentPut+1, uint32(c)) 152 } 153 for c := 0; c < concurrentGet; c++ { 154 go func(n int, lane uint32) { 155 var v *T 156 for i := 0; m.GetLane(lane, &v); i++ { 157 _ = *v 158 } 159 wgGet.Done() 160 }(b.N/concurrentGet+1, uint32(c)) 161 } 162 163 wgPut.Wait() 164 m.Close() 165 wgGet.Wait() 166 runtime.GOMAXPROCS(p) 167 } 168 169 func TestMultiLane_Blocking(t *testing.T) { 170 defer goleak.VerifyNone(t) 171 const N = 1000 172 var m = New(Config{ 173 LaneWidth: 2, 174 QueueSize: 8, 175 }) 176 var wg sync.WaitGroup 177 wg.Add(2) 178 t1 := time.Now() 179 go func(n int) { 180 defer wg.Done() 181 for i := 0; i < n; i++ { 182 m.Put(int64(i)) 183 time.Sleep(1 * time.Microsecond) 184 } 185 m.Close() 186 }(N) 187 go func(n int) { 188 defer wg.Done() 189 var v *int 190 for i := 0; m.Get(&v); i++ { 191 if i != *v { 192 t.Fatalf("Expected %d, but got %d", i, *v) 193 panic(i) 194 } 195 } 196 }(N) 197 wg.Wait() 198 t.Log(time.Since(t1)) 199 }