github.com/etecs-ru/ristretto@v0.9.1/z/calloc_test.go (about)

     1  /*
     2   * Copyright 2020 Dgraph Labs, Inc. and Contributors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package z
    18  
    19  import (
    20  	"fmt"
    21  	"math/rand"
    22  	"sync"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/stretchr/testify/require"
    27  )
    28  
    29  // $ go test -failfast -run xxx -bench . -benchmem  -count 10 > out.txt
    30  // $ benchstat out.txt
    31  // name                 time/op
    32  // Allocation/Pool-8    200µs ± 5%
    33  // Allocation/Calloc-8  100µs ±11%
    34  //
    35  // name                 alloc/op
    36  // Allocation/Pool-8     477B ±29%
    37  // Allocation/Calloc-8  4.00B ± 0%
    38  //
    39  // name                 allocs/op
    40  // Allocation/Pool-8     1.00 ± 0%
    41  // Allocation/Calloc-8   0.00
    42  func BenchmarkAllocation(b *testing.B) {
    43  	b.Run("Pool", func(b *testing.B) {
    44  		pool := sync.Pool{
    45  			New: func() interface{} {
    46  				return make([]byte, 4<<10)
    47  			},
    48  		}
    49  		b.RunParallel(func(pb *testing.PB) {
    50  			source := rand.NewSource(time.Now().UnixNano())
    51  			r := rand.New(source)
    52  			for pb.Next() {
    53  				x := pool.Get().([]byte)
    54  				sz := r.Intn(100) << 10
    55  				if len(x) < sz {
    56  					x = make([]byte, sz)
    57  				}
    58  				r.Read(x)
    59  				pool.Put(x)
    60  			}
    61  		})
    62  	})
    63  
    64  	b.Run("Calloc", func(b *testing.B) {
    65  		b.RunParallel(func(pb *testing.PB) {
    66  			source := rand.NewSource(time.Now().UnixNano())
    67  			r := rand.New(source)
    68  			for pb.Next() {
    69  				sz := r.Intn(100) << 10
    70  				x := Calloc(sz, "test")
    71  				r.Read(x)
    72  				Free(x)
    73  			}
    74  		})
    75  	})
    76  }
    77  
    78  func TestCalloc(t *testing.T) {
    79  	// Check if we're using jemalloc.
    80  	// JE_MALLOC_CONF="abort:true,tcache:false"
    81  
    82  	StatsPrint()
    83  	buf := CallocNoRef(1, "test")
    84  	if len(buf) == 0 {
    85  		t.Skipf("Not using jemalloc. Skipping test.")
    86  	}
    87  	Free(buf)
    88  	require.Equal(t, int64(0), NumAllocBytes())
    89  
    90  	buf1 := Calloc(128, "test")
    91  	require.Equal(t, int64(128), NumAllocBytes())
    92  	buf2 := Calloc(128, "test")
    93  	require.Equal(t, int64(256), NumAllocBytes())
    94  
    95  	Free(buf1)
    96  	require.Equal(t, int64(128), NumAllocBytes())
    97  
    98  	// _ = buf2
    99  	Free(buf2)
   100  	require.Equal(t, int64(0), NumAllocBytes())
   101  	fmt.Println(Leaks())
   102  
   103  	// Double free would panic when debug mode is enabled in jemalloc.
   104  	// Free(buf2)
   105  	// require.Equal(t, int64(0), NumAllocBytes())
   106  }