github.com/reusee/pr3@v0.0.0-20240520031754-49012a37a83e/pool_test.go (about) 1 package pr3 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "math/rand" 7 "sync" 8 "sync/atomic" 9 "testing" 10 ) 11 12 func TestBytesPool(t *testing.T) { 13 pool := NewPool(8, func() []byte { 14 return make([]byte, 8) 15 }) 16 wg := new(sync.WaitGroup) 17 for i := 0; i < 200; i++ { 18 wg.Add(1) 19 i := i 20 go func() { 21 defer wg.Done() 22 for j := 0; j < 200; j++ { 23 var bs []byte 24 elem := pool.Get(&bs) 25 defer elem.Put() 26 binary.PutUvarint(bs, uint64(i)) 27 } 28 }() 29 } 30 wg.Wait() 31 } 32 33 func TestBytesPoolRC(t *testing.T) { 34 pool := NewPool(8, func() []byte { 35 return make([]byte, 8) 36 }) 37 wg := new(sync.WaitGroup) 38 for i := 0; i < 200; i++ { 39 wg.Add(1) 40 i := i 41 go func() { 42 defer wg.Done() 43 for j := 0; j < 200; j++ { 44 var bs []byte 45 elem := pool.Get(&bs) 46 defer elem.Put() 47 nRef := rand.Intn(16) 48 for i := 0; i < nRef; i++ { 49 elem.Inc() 50 } 51 defer func() { 52 for i := 0; i < nRef; i++ { 53 elem.Inc() 54 } 55 }() 56 binary.PutUvarint(bs, uint64(i)) 57 } 58 }() 59 } 60 wg.Wait() 61 } 62 63 func TestBytesPoolRCOverload(t *testing.T) { 64 pool := NewPool(1, func() int { 65 return 42 66 }) 67 var i int 68 pool.Get(&i) 69 var j int 70 elem := pool.Get(&j) 71 elem.Inc() 72 if elem.Put() { 73 t.Fatal() 74 } 75 if !elem.Put() { 76 t.Fatal() 77 } 78 } 79 80 func BenchmarkBytesPool(b *testing.B) { 81 pool := NewPool(8, func() []byte { 82 return make([]byte, 8) 83 }) 84 b.ResetTimer() 85 for i := 0; i < b.N; i++ { 86 var v []byte 87 elem := pool.Get(&v) 88 elem.Put() 89 } 90 } 91 92 func BenchmarkStdSyncPool(b *testing.B) { 93 pool := &sync.Pool{ 94 New: func() any { 95 bs := make([]byte, 8) 96 return &bs 97 }, 98 } 99 b.ResetTimer() 100 for i := 0; i < b.N; i++ { 101 elem := pool.Get().(*[]byte) 102 pool.Put(elem) 103 } 104 } 105 106 func BenchmarkParallelBytesPool(b *testing.B) { 107 pool := NewPool(1024, func() []byte { 108 return make([]byte, 8) 109 }) 110 b.ResetTimer() 111 b.RunParallel(func(pb *testing.PB) { 112 for pb.Next() { 113 var v []byte 114 elem := pool.Get(&v) 115 elem.Put() 116 } 117 }) 118 } 119 120 func BenchmarkParallelStdSyncPool(b *testing.B) { 121 pool := &sync.Pool{ 122 New: func() any { 123 bs := make([]byte, 8) 124 return &bs 125 }, 126 } 127 b.ResetTimer() 128 b.RunParallel(func(pb *testing.PB) { 129 for pb.Next() { 130 elem := pool.Get().(*[]byte) 131 pool.Put(elem) 132 } 133 }) 134 } 135 136 func TestPoolBadPut(t *testing.T) { 137 pool := NewPool(1, func() int { 138 return 42 139 }) 140 var i int 141 elem := pool.Get(&i) 142 elem.Put() 143 func() { 144 defer func() { 145 p := recover() 146 if p == nil { 147 t.Fatal() 148 } 149 if fmt.Sprintf("%v", p) != "bad put" { 150 t.Fatal() 151 } 152 }() 153 elem.Put() 154 }() 155 } 156 157 func TestPoolBadPutRC(t *testing.T) { 158 pool := NewPool(1, func() int { 159 return 42 160 }) 161 var j int 162 pool.Get(&j) 163 var i int 164 elem := pool.Get(&i) 165 elem.Put() 166 func() { 167 defer func() { 168 p := recover() 169 if p == nil { 170 t.Fatal() 171 } 172 if fmt.Sprintf("%v", p) != "bad put" { 173 t.Fatal() 174 } 175 }() 176 elem.Put() 177 }() 178 } 179 180 func BenchmarkPoolDrain(b *testing.B) { 181 pool := NewPool(1, func() []byte { 182 return make([]byte, 8) 183 }) 184 b.ResetTimer() 185 b.RunParallel(func(pb *testing.PB) { 186 for pb.Next() { 187 var v []byte 188 elem := pool.Get(&v) 189 elem.Put() 190 } 191 }) 192 } 193 194 func BenchmarkFastrand(b *testing.B) { 195 for i := 0; i < b.N; i++ { 196 fastrand() 197 } 198 } 199 200 func BenchmarkAtomicAdd(b *testing.B) { 201 n := new(atomic.Uint32) 202 for i := 0; i < b.N; i++ { 203 n.Add(1) 204 } 205 }