github.com/searKing/golang/go@v1.2.117/time/cost.go (about)

     1  package time
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"sort"
     7  	"strings"
     8  	"time"
     9  
    10  	runtime_ "github.com/searKing/golang/go/runtime"
    11  )
    12  
    13  type Cost struct {
    14  	start time.Time
    15  }
    16  
    17  func (c *Cost) Start() {
    18  	c.start = time.Now()
    19  }
    20  
    21  func (c *Cost) Elapse() time.Duration {
    22  	return time.Now().Sub(c.start)
    23  }
    24  
    25  func (c *Cost) ElapseFunc(f func(d time.Duration)) {
    26  	if f != nil {
    27  		f(c.Elapse())
    28  	}
    29  }
    30  
    31  type CostTick struct {
    32  	points   []time.Time
    33  	messages []string
    34  	costs    []time.Duration
    35  	// Lesser reports whether the element with duration i
    36  	// must sort before the element with duration j.
    37  	// sorting in decreasing order of cost if Lesser is nil
    38  	// behaves like Less in sort.Interface
    39  	Lesser func(i time.Duration, j time.Duration) bool
    40  }
    41  
    42  func (c *CostTick) Reset() {
    43  	c.points = nil
    44  	c.messages = nil
    45  	c.costs = nil
    46  }
    47  
    48  func (c *CostTick) Tick(msg string) {
    49  	if msg == "" {
    50  		caller, file, line := runtime_.GetShortCallerFuncFileLine(1)
    51  		msg = fmt.Sprintf("%s() %s:%d", caller, file, line)
    52  	}
    53  	c.points = append(c.points, time.Now())
    54  	c.messages = append(c.messages, msg)
    55  	if len(c.costs) == 0 || len(c.points) == 1 {
    56  		c.costs = append(c.costs, 0)
    57  	} else {
    58  		c.costs = append(c.costs, c.points[len(c.points)-1].Sub(c.points[len(c.points)-2]))
    59  	}
    60  }
    61  
    62  func (c CostTick) String() string {
    63  	var buf strings.Builder
    64  	var scanned bool
    65  	c.Walk(func(idx int, msg string, cost time.Duration, at time.Time) (next bool) {
    66  		if scanned {
    67  			buf.WriteString("\n")
    68  		}
    69  		buf.WriteString(fmt.Sprintf("#%d, msg: %s, cost %s, at %s", idx, msg, cost, at))
    70  		scanned = true
    71  		return true
    72  	})
    73  	return buf.String()
    74  }
    75  
    76  func (c CostTick) Format(s fmt.State, verb rune) {
    77  	switch verb {
    78  	case 'v':
    79  		if s.Flag('+') {
    80  			_, _ = io.WriteString(s, c.String())
    81  		}
    82  		fallthrough
    83  	case 's', 'q':
    84  		var costs []string
    85  		c.Walk(func(idx int, msg string, cost time.Duration, at time.Time) (next bool) {
    86  			costs = append(costs, fmt.Sprintf("%s(%s)", msg, cost))
    87  			return true
    88  		})
    89  		_, _ = fmt.Fprintf(s, "%v", costs)
    90  	}
    91  }
    92  
    93  func (c CostTick) Costs() []time.Duration {
    94  	var costs []time.Duration
    95  	c.Walk(func(idx int, msg string, cost time.Duration, at time.Time) (next bool) {
    96  		costs = append(costs, cost)
    97  		return true
    98  	})
    99  	return costs
   100  }
   101  
   102  // Walk iterate costs
   103  // Walk stop if f(...) returns false.
   104  func (c CostTick) Walk(f func(idx int, msg string, cost time.Duration, at time.Time) (next bool)) {
   105  	if f == nil {
   106  		return
   107  	}
   108  
   109  	for i, p := range c.points {
   110  		if f(i, c.messages[i], c.costs[i], p) {
   111  			continue
   112  		}
   113  		return
   114  	}
   115  }
   116  
   117  // sorting in decreasing order of cost.
   118  func (c CostTick) Len() int { return len(c.points) }
   119  
   120  func (c CostTick) Less(i, j int) bool {
   121  	if c.Lesser != nil {
   122  		return c.Lesser(c.costs[i], c.costs[j])
   123  	}
   124  	return c.costs[i] > c.costs[j]
   125  }
   126  
   127  func (c *CostTick) Swap(i, j int) {
   128  	c.points[i], c.points[j] = c.points[j], c.points[i]
   129  	c.messages[i], c.messages[j] = c.messages[j], c.messages[i]
   130  	c.costs[i], c.costs[j] = c.costs[j], c.costs[i]
   131  }
   132  
   133  // Sort is a convenience method: x.Sort() calls Sort(x).
   134  func (c *CostTick) Sort() { sort.Sort(c) }