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  }