github.com/GoWebProd/gip@v0.0.0-20230623090727-b60d41d5d320/slab/slab_test.go (about) 1 package slab 2 3 import ( 4 "runtime" 5 "sync" 6 "testing" 7 8 "github.com/couchbase/go-slab" 9 10 "github.com/GoWebProd/gip/allocator" 11 "github.com/GoWebProd/gip/pool" 12 ) 13 14 func TestMin(t *testing.T) { 15 s := New(8, 64, 2) 16 17 data := s.Get(2) 18 d := *data 19 20 if len(d) != 2 || cap(d) != 8 { 21 t.Fatalf("bad slice: %d-%d, must be 2-8", len(d), cap(d)) 22 } 23 24 s.Put(data) 25 } 26 27 func TestMax(t *testing.T) { 28 s := New(8, 64, 2) 29 30 data := s.Get(128) 31 d := *data 32 33 if len(d) != 128 || cap(d) != 128 { 34 t.Fatalf("bad slice: %d-%d, must be 128-128", len(d), cap(d)) 35 } 36 37 s.Put(data) 38 } 39 40 func TestMed(t *testing.T) { 41 s := New(8, 64, 2) 42 43 data := s.Get(27) 44 d := *data 45 46 if len(d) != 27 || cap(d) != 32 { 47 t.Fatalf("bad slice: %d-%d, must be 27-32", len(d), cap(d)) 48 } 49 50 s.Put(data) 51 } 52 53 func TestSmallGrowFactor(t *testing.T) { 54 s := New(8, 64, 1.01) 55 56 for i := 0; i < len(s.pools); i++ { 57 if s.sizes[i] != i+8 { 58 t.Fatalf("bad increments on small grow factor: %+v", &s.pools) 59 } 60 } 61 } 62 63 func BenchmarkOurPool(b *testing.B) { 64 s := pool.Pool[[]byte]{} 65 wg := sync.WaitGroup{} 66 67 for i := 0; i < runtime.GOMAXPROCS(0)*10; i++ { 68 wg.Add(1) 69 70 go func() { 71 defer wg.Done() 72 73 for i := 0; i < b.N; i++ { 74 d := s.Get() 75 if d == nil { 76 d = new([]byte) 77 *d = allocator.Alloc(4096) 78 } 79 80 _ = (*d)[:i%4096] 81 82 s.Put(d) 83 } 84 }() 85 } 86 87 wg.Wait() 88 } 89 90 func BenchmarkOur(b *testing.B) { 91 s := New(4096, 4096, 1.1) 92 wg := sync.WaitGroup{} 93 94 for i := 0; i < runtime.GOMAXPROCS(0)*10; i++ { 95 wg.Add(1) 96 97 go func() { 98 defer wg.Done() 99 100 for i := 0; i < b.N; i++ { 101 d := s.Get(i % 4096) 102 103 s.Put(d) 104 } 105 }() 106 } 107 108 wg.Wait() 109 } 110 111 func BenchmarkPool(b *testing.B) { 112 wg := sync.WaitGroup{} 113 pool := sync.Pool{ 114 New: func() interface{} { 115 x := make([]byte, 4096) 116 117 return &x 118 }, 119 } 120 121 for i := 0; i < runtime.GOMAXPROCS(0)*10; i++ { 122 wg.Add(1) 123 124 go func() { 125 defer wg.Done() 126 127 for i := 0; i < b.N; i++ { 128 d := pool.Get().(*[]byte) 129 _ = (*d)[:i%4096] 130 131 pool.Put(d) 132 } 133 }() 134 } 135 136 wg.Wait() 137 } 138 139 func BenchmarkMalloc(b *testing.B) { 140 wg := sync.WaitGroup{} 141 142 for i := 0; i < runtime.GOMAXPROCS(0)*10; i++ { 143 wg.Add(1) 144 145 go func() { 146 defer wg.Done() 147 148 for i := 0; i < b.N; i++ { 149 d := allocator.Alloc(1 + i%4096) 150 151 allocator.Free(d) 152 } 153 }() 154 } 155 156 wg.Wait() 157 } 158 159 func BenchmarkChannel(b *testing.B) { 160 wg := sync.WaitGroup{} 161 n := runtime.GOMAXPROCS(0) * 10 162 pool := make(chan []byte, n) 163 164 for i := 0; i < n; i++ { 165 wg.Add(1) 166 167 go func() { 168 defer wg.Done() 169 170 for i := 0; i < b.N; i++ { 171 var d []byte 172 173 select { 174 case d = <-pool: 175 176 default: 177 d = make([]byte, 4096) 178 } 179 180 _ = d[:i%4096] 181 182 pool <- d 183 } 184 }() 185 } 186 187 wg.Wait() 188 } 189 190 func BenchmarkCouchbase(b *testing.B) { 191 s := slab.NewArena(48, 4096, 1.1, nil) 192 m := sync.Mutex{} 193 wg := sync.WaitGroup{} 194 195 for i := 0; i < runtime.GOMAXPROCS(0)*10; i++ { 196 wg.Add(1) 197 198 go func() { 199 defer wg.Done() 200 201 for i := 0; i < b.N; i++ { 202 m.Lock() 203 204 d := s.Alloc(i % 4096) 205 206 s.DecRef(d) 207 m.Unlock() 208 } 209 }() 210 } 211 212 wg.Wait() 213 } 214 215 func BenchmarkMake(b *testing.B) { 216 wg := sync.WaitGroup{} 217 218 for i := 0; i < runtime.GOMAXPROCS(0)*10; i++ { 219 wg.Add(1) 220 221 go func() { 222 defer wg.Done() 223 224 for i := 0; i < b.N; i++ { 225 d := make([]byte, i%4096) 226 _ = d 227 } 228 }() 229 } 230 231 wg.Wait() 232 }