File: timer.go

package info (click to toggle)
mumax3 3.11.1-1
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 10,668 kB
  • sloc: makefile: 194; ansic: 155; sh: 86; javascript: 16
file content (104 lines) | stat: -rw-r--r-- 2,066 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package timer

import (
	"fmt"
	"io"
	"sort"
	"time"
)

var (
	clocks     map[string]*clock
	firstStart time.Time
)

func Start(key string) {
	if clocks == nil {
		clocks = make(map[string]*clock)
		firstStart = time.Now()
	}

	if c, ok := clocks[key]; ok {
		c.Start()
	} else {
		clocks[key] = new(clock)
		// do not start, first run = warmup time
	}
}

func Stop(key string) {
	clocks[key].Stop()
}

type clock struct {
	total       time.Duration
	started     time.Time
	invocations int
}

func (c *clock) Start() {
	c.started = time.Now()
	c.invocations++
}

func (c *clock) Stop() {
	if (c.started == time.Time{}) {
		return // not started
	}
	d := time.Since(c.started)
	c.total += d
	c.started = time.Time{}
}

// entry for sorted output by Print()
type entry struct {
	name        string
	total       time.Duration
	invocations int
	pct         float32
}

func (e *entry) String() string {
	perOp := time.Duration(0)
	if int64(e.invocations) != 0 {
		perOp = time.Duration(int64(e.total) / int64(e.invocations))
	}
	return fmt.Sprint(pad(e.name), pad(fmt.Sprint(e.invocations, "x")), perOp, "/op\t", e.pct, " %\t", e.total, " total")
}

func pad(s string) string {
	if len(s) >= 20 {
		return s
	}
	return s + "                    "[:20-len(s)]
}

type entries []entry

func (l entries) Len() int           { return len(l) }
func (l entries) Less(i, j int) bool { return l[i].total > l[j].total }
func (l entries) Swap(i, j int)      { l[i], l[j] = l[j], l[i] }

func Print(out io.Writer) {
	if clocks == nil {
		return
	}
	wallTime := time.Since(firstStart)
	lines := make(entries, 0, len(clocks))
	var accounted time.Duration
	for k, v := range clocks {
		pct := 100 * float32(int64(v.total)) / float32(int64(wallTime))
		lines = append(lines, entry{k, v.total, v.invocations, pct})
		accounted += v.total
	}

	unaccounted := wallTime - accounted
	pct := 100 * float32(int64(unaccounted)) / float32(int64(wallTime))
	lines = append(lines, entry{"NOT TIMED", unaccounted, 1, pct})

	sort.Sort(lines)

	for _, l := range lines {
		fmt.Fprintln(out, &l)
	}
}