github.com/karrick/go@v0.0.0-20170817181416-d5b0ec858b37/test/bench/garbage/tree2.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"flag"
     9  	"fmt"
    10  	"log"
    11  	"os"
    12  	"runtime"
    13  	"runtime/pprof"
    14  	"time"
    15  	"unsafe"
    16  )
    17  
    18  const BranchingFactor = 4
    19  
    20  type Object struct {
    21  	child [BranchingFactor]*Object
    22  }
    23  
    24  var (
    25  	cpus       = flag.Int("cpus", 1, "number of cpus to use")
    26  	heapsize   = flag.Int64("heapsize", 100*1024*1024, "size of the heap in bytes")
    27  	cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
    28  
    29  	lastPauseNs uint64 = 0
    30  	lastFree    uint64 = 0
    31  	heap        *Object
    32  	calls       [20]int
    33  	numobjects  int64
    34  	memstats    runtime.MemStats
    35  )
    36  
    37  func buildHeap() {
    38  	objsize := int64(unsafe.Sizeof(Object{}))
    39  	heap, _ = buildTree(float64(objsize), float64(*heapsize), 0)
    40  	fmt.Printf("*** built heap: %.0f MB; (%d objects * %d bytes)\n",
    41  		float64(*heapsize)/1048576, numobjects, objsize)
    42  }
    43  
    44  func buildTree(objsize, size float64, depth int) (*Object, float64) {
    45  	calls[depth]++
    46  	x := &Object{}
    47  	numobjects++
    48  	subtreeSize := (size - objsize) / BranchingFactor
    49  	alloc := objsize
    50  	for i := 0; i < BranchingFactor && alloc < size; i++ {
    51  		c, n := buildTree(objsize, subtreeSize, depth+1)
    52  		x.child[i] = c
    53  		alloc += n
    54  	}
    55  	return x, alloc
    56  }
    57  
    58  func gc() {
    59  	runtime.GC()
    60  	runtime.ReadMemStats(&memstats)
    61  	pause := memstats.PauseTotalNs
    62  	inuse := memstats.Alloc
    63  	free := memstats.TotalAlloc - inuse
    64  	fmt.Printf("gc pause: %8.3f ms; collect: %8.0f MB; heapsize: %8.0f MB\n",
    65  		float64(pause-lastPauseNs)/1e6,
    66  		float64(free-lastFree)/1048576,
    67  		float64(inuse)/1048576)
    68  	lastPauseNs = pause
    69  	lastFree = free
    70  }
    71  
    72  func main() {
    73  	flag.Parse()
    74  	buildHeap()
    75  	runtime.GOMAXPROCS(*cpus)
    76  	runtime.ReadMemStats(&memstats)
    77  	lastPauseNs = memstats.PauseTotalNs
    78  	lastFree = memstats.TotalAlloc - memstats.Alloc
    79  	if *cpuprofile != "" {
    80  		f, err := os.Create(*cpuprofile)
    81  		if err != nil {
    82  			log.Fatal(err)
    83  		}
    84  		pprof.StartCPUProfile(f)
    85  		defer pprof.StopCPUProfile()
    86  	}
    87  	const N = 10
    88  	var t0 time.Time
    89  	for i := 0; i < N; i++ {
    90  		t0 = time.Now()
    91  		gc()
    92  	}
    93  	// Standard gotest benchmark output, collected by build dashboard.
    94  	gcstats("BenchmarkTree2", N, time.Now().Sub(t0))
    95  }