launchpad.net/gocheck@v0.0.0-20140225173054-000000000087/benchmark.go (about)

     1  // Copyright 2009 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 gocheck
     6  
     7  import (
     8  	"fmt"
     9  	"time"
    10  )
    11  
    12  // testingB is a type passed to Benchmark functions to manage benchmark
    13  // timing and to specify the number of iterations to run.
    14  type timer struct {
    15  	start     time.Time // Time test or benchmark started
    16  	duration  time.Duration
    17  	N         int
    18  	bytes     int64
    19  	timerOn   bool
    20  	benchTime time.Duration
    21  }
    22  
    23  // StartTimer starts timing a test. This function is called automatically
    24  // before a benchmark starts, but it can also used to resume timing after
    25  // a call to StopTimer.
    26  func (c *C) StartTimer() {
    27  	if !c.timerOn {
    28  		c.start = time.Now()
    29  		c.timerOn = true
    30  	}
    31  }
    32  
    33  // StopTimer stops timing a test. This can be used to pause the timer
    34  // while performing complex initialization that you don't
    35  // want to measure.
    36  func (c *C) StopTimer() {
    37  	if c.timerOn {
    38  		c.duration += time.Now().Sub(c.start)
    39  		c.timerOn = false
    40  	}
    41  }
    42  
    43  // ResetTimer sets the elapsed benchmark time to zero.
    44  // It does not affect whether the timer is running.
    45  func (c *C) ResetTimer() {
    46  	if c.timerOn {
    47  		c.start = time.Now()
    48  	}
    49  	c.duration = 0
    50  }
    51  
    52  // SetBytes informs the number of bytes that the benchmark processes
    53  // on each iteration. If this is called in a benchmark it will also
    54  // report MB/s.
    55  func (c *C) SetBytes(n int64) {
    56  	c.bytes = n
    57  }
    58  
    59  func (c *C) nsPerOp() int64 {
    60  	if c.N <= 0 {
    61  		return 0
    62  	}
    63  	return c.duration.Nanoseconds() / int64(c.N)
    64  }
    65  
    66  func (c *C) mbPerSec() float64 {
    67  	if c.bytes <= 0 || c.duration <= 0 || c.N <= 0 {
    68  		return 0
    69  	}
    70  	return (float64(c.bytes) * float64(c.N) / 1e6) / c.duration.Seconds()
    71  }
    72  
    73  func (c *C) timerString() string {
    74  	if c.N <= 0 {
    75  		return fmt.Sprintf("%3.3fs", float64(c.duration.Nanoseconds())/1e9)
    76  	}
    77  	mbs := c.mbPerSec()
    78  	mb := ""
    79  	if mbs != 0 {
    80  		mb = fmt.Sprintf("\t%7.2f MB/s", mbs)
    81  	}
    82  	nsop := c.nsPerOp()
    83  	ns := fmt.Sprintf("%10d ns/op", nsop)
    84  	if c.N > 0 && nsop < 100 {
    85  		// The format specifiers here make sure that
    86  		// the ones digits line up for all three possible formats.
    87  		if nsop < 10 {
    88  			ns = fmt.Sprintf("%13.2f ns/op", float64(c.duration.Nanoseconds())/float64(c.N))
    89  		} else {
    90  			ns = fmt.Sprintf("%12.1f ns/op", float64(c.duration.Nanoseconds())/float64(c.N))
    91  		}
    92  	}
    93  	return fmt.Sprintf("%8d\t%s%s", c.N, ns, mb)
    94  }
    95  
    96  func min(x, y int) int {
    97  	if x > y {
    98  		return y
    99  	}
   100  	return x
   101  }
   102  
   103  func max(x, y int) int {
   104  	if x < y {
   105  		return y
   106  	}
   107  	return x
   108  }
   109  
   110  // roundDown10 rounds a number down to the nearest power of 10.
   111  func roundDown10(n int) int {
   112  	var tens = 0
   113  	// tens = floor(log_10(n))
   114  	for n > 10 {
   115  		n = n / 10
   116  		tens++
   117  	}
   118  	// result = 10^tens
   119  	result := 1
   120  	for i := 0; i < tens; i++ {
   121  		result *= 10
   122  	}
   123  	return result
   124  }
   125  
   126  // roundUp rounds x up to a number of the form [1eX, 2eX, 5eX].
   127  func roundUp(n int) int {
   128  	base := roundDown10(n)
   129  	if n < (2 * base) {
   130  		return 2 * base
   131  	}
   132  	if n < (5 * base) {
   133  		return 5 * base
   134  	}
   135  	return 10 * base
   136  }