github.com/GoWebProd/gip@v0.0.0-20230623090727-b60d41d5d320/pool/pool_test.go (about)

     1  package pool
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"runtime"
     7  	"sync"
     8  	"testing"
     9  	"time"
    10  	_ "unsafe"
    11  
    12  	"github.com/GoWebProd/gip/allocator"
    13  	"github.com/GoWebProd/gip/rtime"
    14  )
    15  
    16  func TestParallel(t *testing.T) {
    17  	proc := runtime.GOMAXPROCS(0)
    18  	p := Pool[[]byte]{}
    19  	zeroBytes := make([]byte, 128)
    20  
    21  	var (
    22  		wg sync.WaitGroup
    23  		e  bool
    24  	)
    25  
    26  	for i := 0; i < proc*100; i++ {
    27  		wg.Add(1)
    28  
    29  		number := i
    30  		template := fmt.Sprintf("goroutine %d", number)
    31  
    32  		go func() {
    33  			defer wg.Done()
    34  
    35  			for i := 0; i < 10000; i++ {
    36  				b := p.Get()
    37  				if b == nil {
    38  					b = new([]byte)
    39  					*b = allocator.Alloc(128)
    40  				}
    41  
    42  				if !bytes.Equal(*b, zeroBytes) {
    43  					t.Errorf("bad value: %v", string((*b)[:len(template)]))
    44  
    45  					e = true
    46  				}
    47  
    48  				copy(*b, []byte(template))
    49  				time.Sleep(time.Millisecond)
    50  				copy(*b, zeroBytes)
    51  				p.Put(b)
    52  			}
    53  		}()
    54  	}
    55  
    56  	wg.Wait()
    57  
    58  	if e {
    59  		t.Fatal("error raised")
    60  	}
    61  }
    62  
    63  func TestPool(t *testing.T) {
    64  	p := Pool[[]byte]{}
    65  
    66  	b1 := p.Get()
    67  	if b1 != nil {
    68  		t.Fatalf("bad length: %d", len(*b1))
    69  	}
    70  
    71  	b1 = new([]byte)
    72  	*b1 = allocator.Alloc(5)
    73  
    74  	(*b1)[0] = 'h'
    75  	(*b1)[1] = 'e'
    76  	(*b1)[2] = 'l'
    77  	(*b1)[3] = 'l'
    78  	(*b1)[4] = 'o'
    79  
    80  	b2 := p.Get()
    81  	if b2 != nil {
    82  		t.Fatalf("bad length: %d", len(*b2))
    83  	}
    84  
    85  	p.Put(b1)
    86  
    87  	b3 := p.Get()
    88  	if len(*b3) != 5 {
    89  		t.Fatalf("bad length: %d", len(*b1))
    90  	}
    91  
    92  	if !bytes.Equal(*b1, *b3) {
    93  		t.Fatalf("b1 != b3: %v != %v", b1, b3)
    94  	}
    95  }
    96  
    97  func BenchmarkCreateDefault(b *testing.B) {
    98  	for i := 0; i < b.N; i++ {
    99  		x := make([]byte, 128)
   100  		copy(x, "test")
   101  	}
   102  }
   103  
   104  func BenchmarkCreateOur(b *testing.B) {
   105  	for i := 0; i < b.N; i++ {
   106  		x := allocator.Alloc(128)
   107  		
   108  		copy(x, "test")
   109  
   110  		allocator.Free(x)
   111  	}
   112  }
   113  
   114  func BenchmarkDefault(b *testing.B) {
   115  	t := sync.Pool{
   116  		New: func() interface{} {
   117  			x := make([]byte, 128)
   118  
   119  			return &x
   120  		},
   121  	}
   122  
   123  	for i := 0; i < b.N; i++ {
   124  		x := t.Get().(*[]byte)
   125  		copy(*x, "test")
   126  		t.Put(x)
   127  	}
   128  }
   129  
   130  func BenchmarkOur(b *testing.B) {
   131  	t := Pool[[]byte]{}
   132  
   133  	for i := 0; i < b.N; i++ {
   134  		x := t.Get()
   135  		if x == nil {
   136  			x = new([]byte)
   137  			*x = allocator.Alloc(128)
   138  		}
   139  
   140  		copy(*x, "test")
   141  		t.Put(x)
   142  	}
   143  }
   144  
   145  func BenchmarkPin(b *testing.B) {
   146  	g := runtime.GOMAXPROCS(0)
   147  
   148  	for i := 0; i < b.N; i++ {
   149  		n := rtime.ProcPin()
   150  		if n >= g {
   151  			b.Fatal(n)
   152  		}
   153  
   154  		rtime.ProcUnpin()
   155  	}
   156  }
   157  
   158  func BenchmarkLock(b *testing.B) {
   159  	for i := 0; i < b.N; i++ {
   160  		runtime.LockOSThread()
   161  		runtime.UnlockOSThread()
   162  	}
   163  }