github.com/outcaste-io/ristretto@v0.2.3/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  	"sync"
    22  	"testing"
    23  	"time"
    24  
    25  	"math/rand"
    26  
    27  	"github.com/stretchr/testify/require"
    28  )
    29  
    30  // $ go test -failfast -run xxx -bench . -benchmem  -count 10 > out.txt
    31  // $ benchstat out.txt
    32  // name                 time/op
    33  // Allocation/Pool-8    200µs ± 5%
    34  // Allocation/Calloc-8  100µs ±11%
    35  //
    36  // name                 alloc/op
    37  // Allocation/Pool-8     477B ±29%
    38  // Allocation/Calloc-8  4.00B ± 0%
    39  //
    40  // name                 allocs/op
    41  // Allocation/Pool-8     1.00 ± 0%
    42  // Allocation/Calloc-8   0.00
    43  func BenchmarkAllocation(b *testing.B) {
    44  	b.Run("Pool", func(b *testing.B) {
    45  		pool := sync.Pool{
    46  			New: func() interface{} {
    47  				return make([]byte, 4<<10)
    48  			},
    49  		}
    50  		b.RunParallel(func(pb *testing.PB) {
    51  			source := rand.NewSource(time.Now().UnixNano())
    52  			r := rand.New(source)
    53  			for pb.Next() {
    54  				x := pool.Get().([]byte)
    55  				sz := r.Intn(100) << 10
    56  				if len(x) < sz {
    57  					x = make([]byte, sz)
    58  				}
    59  				r.Read(x)
    60  				pool.Put(x)
    61  			}
    62  		})
    63  	})
    64  
    65  	b.Run("Calloc", func(b *testing.B) {
    66  		b.RunParallel(func(pb *testing.PB) {
    67  			source := rand.NewSource(time.Now().UnixNano())
    68  			r := rand.New(source)
    69  			for pb.Next() {
    70  				sz := r.Intn(100) << 10
    71  				x := Calloc(sz, "test")
    72  				r.Read(x)
    73  				Free(x)
    74  			}
    75  		})
    76  	})
    77  }
    78  
    79  func TestCalloc(t *testing.T) {
    80  	// Check if we're using jemalloc.
    81  	// JE_MALLOC_CONF="abort:true,tcache:false"
    82  
    83  	StatsPrint()
    84  	buf := CallocNoRef(1, "test")
    85  	if len(buf) == 0 {
    86  		t.Skipf("Not using jemalloc. Skipping test.")
    87  	}
    88  	Free(buf)
    89  	require.Equal(t, int64(0), NumAllocBytes())
    90  
    91  	buf1 := Calloc(128, "test")
    92  	require.Equal(t, int64(128), NumAllocBytes())
    93  	buf2 := Calloc(128, "test")
    94  	require.Equal(t, int64(256), NumAllocBytes())
    95  
    96  	Free(buf1)
    97  	require.Equal(t, int64(128), NumAllocBytes())
    98  
    99  	// _ = buf2
   100  	Free(buf2)
   101  	require.Equal(t, int64(0), NumAllocBytes())
   102  	fmt.Println(Leaks())
   103  
   104  	// Double free would panic when debug mode is enabled in jemalloc.
   105  	// Free(buf2)
   106  	// require.Equal(t, int64(0), NumAllocBytes())
   107  }