github.com/ronaksoft/rony@v0.16.26-0.20230807065236-1743dbfe6959/pools/bytes_test.go (about)

     1  package pools_test
     2  
     3  import (
     4  	"crypto/rand"
     5  	"reflect"
     6  	"strconv"
     7  	"testing"
     8  	"unsafe"
     9  
    10  	"github.com/ronaksoft/rony/pools"
    11  )
    12  
    13  /*
    14     Creation Time: 2020 - Aug - 28
    15     Created by:  (ehsan)
    16     Maintainers:
    17        1.  Ehsan N. Moosa (E2)
    18     Auditor: Ehsan N. Moosa (E2)
    19     Copyright Ronak Software Group 2020
    20  */
    21  
    22  func TestByteSlicePoolGet(t *testing.T) {
    23  	for _, test := range []struct {
    24  		min      int
    25  		max      int
    26  		len      int
    27  		cap      int
    28  		exactCap int
    29  	}{
    30  		{
    31  			min:      0,
    32  			max:      64,
    33  			len:      10,
    34  			cap:      24,
    35  			exactCap: 32,
    36  		},
    37  		{
    38  			min:      0,
    39  			max:      0,
    40  			len:      10,
    41  			cap:      24,
    42  			exactCap: 24,
    43  		},
    44  	} {
    45  		t.Run("", func(t *testing.T) {
    46  			p := pools.NewByteSlice(test.min, test.max)
    47  			act := p.Get(test.len, test.cap)
    48  			if n := len(act); n != test.len {
    49  				t.Errorf(
    50  					"Get(%d, _) retured %d-len slice; want %[1]d",
    51  					test.len, n,
    52  				)
    53  			}
    54  			if c := cap(act); c < test.cap {
    55  				t.Errorf(
    56  					"Get(_, %d) retured %d-cap slice; want at least %[1]d",
    57  					test.cap, c,
    58  				)
    59  			}
    60  			if c := cap(act); test.exactCap != 0 && c != test.exactCap {
    61  				t.Errorf(
    62  					"Get(_, %d) retured %d-cap slice; want exact %d",
    63  					test.cap, c, test.exactCap,
    64  				)
    65  			}
    66  		})
    67  	}
    68  }
    69  
    70  func TestByteSlicePoolPut(t *testing.T) {
    71  	p := pools.NewByteSlice(0, 32)
    72  
    73  	miss := make([]byte, 5)
    74  	_, _ = rand.Read(miss)
    75  	p.Put(miss) // Should not reuse.
    76  
    77  	hit := make([]byte, 8)
    78  	_, _ = rand.Read(hit)
    79  	p.Put(hit) // Should reuse.
    80  
    81  	b := p.GetLen(5)
    82  	if data(b) == data(miss) {
    83  		t.Fatalf("unexpected reuse")
    84  	}
    85  	if data(b) != data(hit) {
    86  		t.Fatalf("want reuse")
    87  	}
    88  }
    89  
    90  func data(p []byte) uintptr {
    91  	hdr := (*reflect.SliceHeader)(unsafe.Pointer(&p))
    92  
    93  	return hdr.Data
    94  }
    95  
    96  func BenchmarkPool(b *testing.B) {
    97  	for _, size := range []int{
    98  		1 << 4,
    99  		1 << 5,
   100  		1 << 6,
   101  		1 << 7,
   102  		1 << 8,
   103  		1 << 9,
   104  	} {
   105  		b.Run(strconv.Itoa(size)+"(pool(slice))", func(b *testing.B) {
   106  			b.ReportAllocs()
   107  			b.RunParallel(func(pb *testing.PB) {
   108  				for pb.Next() {
   109  					p := pools.Bytes.GetLen(size)
   110  					pools.Bytes.Put(p)
   111  				}
   112  			})
   113  		})
   114  		b.Run(strconv.Itoa(size)+"(pool(buffer))", func(b *testing.B) {
   115  			b.ReportAllocs()
   116  			b.RunParallel(func(pb *testing.PB) {
   117  				for pb.Next() {
   118  					p := pools.Buffer.GetLen(size)
   119  					pools.Buffer.Put(p)
   120  				}
   121  			})
   122  		})
   123  		b.Run(strconv.Itoa(size)+"(make)", func(b *testing.B) {
   124  			b.ReportAllocs()
   125  			b.RunParallel(func(pb *testing.PB) {
   126  				for pb.Next() {
   127  					_ = make([]byte, size)
   128  				}
   129  			})
   130  		})
   131  	}
   132  }