@@ -11,12 +11,16 @@ import (
11
11
)
12
12
13
13
type CaseDefinition struct {
14
- Bench BenchCase
15
- Count int
16
- Size int
17
- Runtime time.Duration
18
-
19
- startAt time.Time
14
+ Bench BenchCase
15
+ Count int
16
+ Size int
17
+ RequiredIterations int
18
+ Runtime time.Duration
19
+
20
+ cumulativeRuntime time.Duration
21
+ elapsed time.Duration
22
+ startAt time.Time
23
+ isRunning bool
20
24
}
21
25
22
26
// TimerManager is a subset of the testing.B tool, used to manage
@@ -29,19 +33,21 @@ type TimerManager interface {
29
33
30
34
func (c * CaseDefinition ) ResetTimer () {
31
35
c .startAt = time .Now ()
32
- c .Runtime = 0
36
+ c .elapsed = 0
37
+ c .isRunning = true
33
38
}
34
39
35
40
func (c * CaseDefinition ) StartTimer () {
36
41
c .startAt = time .Now ()
42
+ c .isRunning = true
37
43
}
38
44
39
45
func (c * CaseDefinition ) StopTimer () {
40
- if c . startAt . IsZero () {
46
+ if ! c . isRunning {
41
47
return
42
48
}
43
- c .Runtime += time .Since (c .startAt )
44
- c .startAt = time. Time {}
49
+ c .elapsed += time .Since (c .startAt )
50
+ c .isRunning = false
45
51
}
46
52
47
53
func (c * CaseDefinition ) roundedRuntime () time.Duration {
@@ -56,39 +62,57 @@ func (c *CaseDefinition) Run(ctx context.Context) *BenchResult {
56
62
Operations : c .Count ,
57
63
}
58
64
var cancel context.CancelFunc
59
- ctx , cancel = context .WithTimeout (ctx , ExecutionTimeout )
65
+ ctx , cancel = context .WithTimeout (ctx , 2 * ExecutionTimeout )
60
66
defer cancel ()
61
67
62
68
fmt .Println ("=== RUN" , out .Name )
63
- c .startAt = time .Now ()
69
+ if c .RequiredIterations == 0 {
70
+ c .RequiredIterations = MinIterations
71
+ }
64
72
73
+ benchRepeat:
65
74
for {
66
- if time .Since (c .startAt ) > c .Runtime {
67
- if out .Trials >= MinIterations {
75
+ if ctx .Err () != nil {
76
+ break
77
+ }
78
+ if c .cumulativeRuntime >= c .Runtime {
79
+ if out .Trials >= c .RequiredIterations {
68
80
break
69
- } else if ctx . Err () != nil {
81
+ } else if c . cumulativeRuntime >= ExecutionTimeout {
70
82
break
71
83
}
72
84
}
85
+
73
86
res := Result {
74
87
Iterations : c .Count ,
75
88
}
76
89
77
90
c .StartTimer ()
78
91
res .Error = c .Bench (ctx , c , c .Count )
79
92
c .StopTimer ()
80
- res .Duration = c .Runtime
81
-
82
- if res .Error == context .Canceled {
83
- break
93
+ res .Duration = c .elapsed
94
+ c .cumulativeRuntime += res .Duration
95
+
96
+ switch res .Error {
97
+ case context .DeadlineExceeded :
98
+ break benchRepeat
99
+ case context .Canceled :
100
+ break benchRepeat
101
+ case nil :
102
+ out .Trials ++
103
+ c .elapsed = 0
104
+ out .Raw = append (out .Raw , res )
105
+ default :
106
+ continue
84
107
}
85
108
86
- out .Trials ++
87
- out .Raw = append (out .Raw , res )
88
109
}
89
110
90
111
out .Duration = out .totalDuration ()
112
+ fmt .Printf (" --- REPORT: count=%d trials=%d requiredTrials=%d runtime=%s\n " ,
113
+ c .Count , out .Trials , c .RequiredIterations , c .Runtime )
91
114
if out .HasErrors () {
115
+ fmt .Printf (" --- ERRORS: %s\n " , strings .Join (out .errReport (), "\n " ))
92
116
fmt .Printf ("--- FAIL: %s (%s)\n " , out .Name , out .roundedRuntime ())
93
117
} else {
94
118
fmt .Printf ("--- PASS: %s (%s)\n " , out .Name , out .roundedRuntime ())
0 commit comments