github.com/moontrade/nogc@v0.1.7/collections/queue/lock_free_test.go (about) 1 package queue 2 3 import ( 4 "github.com/moontrade/nogc" 5 "runtime" 6 "sync" 7 "sync/atomic" 8 "testing" 9 ) 10 11 func TestLockFreeQueue(t *testing.T) { 12 const taskNum = 50000000 13 nogc.AllocZeroed(24) 14 q := AllocLockFreeQueue() 15 16 b := nogc.AllocBytes(24) 17 b.Free() 18 19 var wg sync.WaitGroup 20 goroutines := 100 21 wg.Add(goroutines) 22 for i := 0; i < goroutines; i++ { 23 go func() { 24 defer wg.Done() 25 for i := 0; i < taskNum/goroutines; i++ { 26 task := nogc.AllocBytes(24) 27 q.Enqueue(task) 28 } 29 }() 30 } 31 32 var counter int32 33 wg.Add(goroutines) 34 for i := 0; i < goroutines; i++ { 35 go func() { 36 defer wg.Done() 37 for { 38 task := q.Dequeue() 39 if !task.IsNil() { 40 atomic.AddInt32(&counter, 1) 41 task.Free() 42 } else { 43 break 44 } 45 } 46 }() 47 } 48 49 wg.Wait() 50 51 t.Logf("sent and received all %d tasks", taskNum) 52 } 53 54 func Benchmark(b *testing.B) { 55 b.Run("queue", func(b *testing.B) { 56 value := nogc.BytesOfString("hello") 57 q := AllocLockFreeQueue() 58 wg := &sync.WaitGroup{} 59 startWg := &sync.WaitGroup{} 60 startWg.Add(1) 61 62 wg.Add(1) 63 go func() { 64 defer wg.Done() 65 runtime.LockOSThread() 66 defer runtime.UnlockOSThread() 67 startWg.Wait() 68 b.ResetTimer() 69 b.ReportAllocs() 70 for i := 0; i < b.N; i++ { 71 q.Enqueue(value) 72 } 73 }() 74 wg.Add(1) 75 go func() { 76 defer wg.Done() 77 runtime.LockOSThread() 78 defer runtime.UnlockOSThread() 79 startWg.Wait() 80 count := 0 81 var v nogc.Bytes 82 for { 83 if count >= b.N { 84 break 85 } 86 v = q.Dequeue() 87 if !v.IsNil() { 88 count++ 89 } 90 } 91 }() 92 93 startWg.Done() 94 wg.Wait() 95 }) 96 97 b.Run("chan buf 1", func(b *testing.B) { 98 value := nogc.BytesOfString("hello") 99 wg := &sync.WaitGroup{} 100 startWg := &sync.WaitGroup{} 101 startWg.Add(1) 102 103 ch := make(chan nogc.Bytes, 64) 104 defer close(ch) 105 106 wg.Add(1) 107 go func() { 108 defer wg.Done() 109 startWg.Wait() 110 b.ResetTimer() 111 b.ReportAllocs() 112 for i := 0; i < b.N; i++ { 113 ch <- value 114 } 115 }() 116 wg.Add(1) 117 go func() { 118 defer wg.Done() 119 startWg.Wait() 120 count := 0 121 var v nogc.Bytes 122 for { 123 if count >= b.N { 124 break 125 } 126 v = <-ch 127 if !v.IsNil() { 128 count++ 129 } 130 } 131 }() 132 133 startWg.Done() 134 wg.Wait() 135 }) 136 }