Skip to content

Commit 545effe

Browse files
committed
GODRIVER-477: fix measurement error and resource useage
Change-Id: I73796712e2346f3cf52c1ecbca401bfeffc7532e
1 parent 75948c7 commit 545effe

File tree

6 files changed

+101
-48
lines changed

6 files changed

+101
-48
lines changed

.evergreen/config.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,13 @@ tasks:
334334

335335
- name: perf
336336
tags: ["performance"]
337+
exec_timeout_secs: 7200
337338
commands:
339+
- func: bootstrap-mongo-orchestration
340+
vars:
341+
TOPOLOGY: "server"
342+
AUTH: "noauth"
343+
SSL: "nossl"
338344
- func: run-make
339345
vars:
340346
targets: driver-benchmark

benchmark/harness.go

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@ import (
99
)
1010

1111
const (
12-
ExecutionTimeout = 5 * time.Minute
13-
StandardRuntime = time.Minute
14-
MinimumRuntime = 10 * time.Second
15-
MinIterations = 100
12+
five = 5
13+
ten = 2 * five
14+
hundred = ten * ten
15+
thousand = ten * hundred
16+
tenThousand = ten * thousand
17+
hundredThousand = hundred * thousand
18+
million = hundred * hundredThousand
19+
halfMillion = five * hundredThousand
1620

17-
ten = 10
18-
hundred = ten * ten
19-
thousand = ten * hundred
20-
tenThousand = ten * thousand
21+
ExecutionTimeout = five * time.Minute
22+
StandardRuntime = time.Minute
23+
MinimumRuntime = five * time.Second
24+
MinIterations = hundred
2125
)
2226

2327
type BenchCase func(context.Context, TimerManager, int) error
@@ -36,16 +40,18 @@ func WrapCase(bench BenchCase) BenchFunction {
3640
func getAllCases() []*CaseDefinition {
3741
return []*CaseDefinition{
3842
{
39-
Bench: CanaryIncCase,
40-
Count: hundred,
41-
Size: -1,
42-
Runtime: MinimumRuntime,
43+
Bench: CanaryIncCase,
44+
Count: million,
45+
Size: -1,
46+
Runtime: MinimumRuntime,
47+
RequiredIterations: ten,
4348
},
4449
{
45-
Bench: GlobalCanaryIncCase,
46-
Count: hundred,
47-
Size: -1,
48-
Runtime: MinimumRuntime,
50+
Bench: GlobalCanaryIncCase,
51+
Count: million,
52+
Size: -1,
53+
Runtime: MinimumRuntime,
54+
RequiredIterations: ten,
4955
},
5056
{
5157
Bench: BSONFlatDocumentEncoding,
@@ -216,10 +222,11 @@ func getAllCases() []*CaseDefinition {
216222
Runtime: StandardRuntime,
217223
},
218224
{
219-
Bench: MultiInsertLargeDocument,
220-
Count: ten,
221-
Size: 27310890,
222-
Runtime: StandardRuntime,
225+
Bench: MultiInsertLargeDocument,
226+
Count: ten,
227+
Size: 27310890,
228+
Runtime: StandardRuntime,
229+
RequiredIterations: tenThousand,
223230
},
224231
}
225232
}

benchmark/harness_case.go

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ import (
1111
)
1212

1313
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
2024
}
2125

2226
// TimerManager is a subset of the testing.B tool, used to manage
@@ -29,19 +33,21 @@ type TimerManager interface {
2933

3034
func (c *CaseDefinition) ResetTimer() {
3135
c.startAt = time.Now()
32-
c.Runtime = 0
36+
c.elapsed = 0
37+
c.isRunning = true
3338
}
3439

3540
func (c *CaseDefinition) StartTimer() {
3641
c.startAt = time.Now()
42+
c.isRunning = true
3743
}
3844

3945
func (c *CaseDefinition) StopTimer() {
40-
if c.startAt.IsZero() {
46+
if !c.isRunning {
4147
return
4248
}
43-
c.Runtime += time.Since(c.startAt)
44-
c.startAt = time.Time{}
49+
c.elapsed += time.Since(c.startAt)
50+
c.isRunning = false
4551
}
4652

4753
func (c *CaseDefinition) roundedRuntime() time.Duration {
@@ -56,39 +62,57 @@ func (c *CaseDefinition) Run(ctx context.Context) *BenchResult {
5662
Operations: c.Count,
5763
}
5864
var cancel context.CancelFunc
59-
ctx, cancel = context.WithTimeout(ctx, ExecutionTimeout)
65+
ctx, cancel = context.WithTimeout(ctx, 2*ExecutionTimeout)
6066
defer cancel()
6167

6268
fmt.Println("=== RUN", out.Name)
63-
c.startAt = time.Now()
69+
if c.RequiredIterations == 0 {
70+
c.RequiredIterations = MinIterations
71+
}
6472

73+
benchRepeat:
6574
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 {
6880
break
69-
} else if ctx.Err() != nil {
81+
} else if c.cumulativeRuntime >= ExecutionTimeout {
7082
break
7183
}
7284
}
85+
7386
res := Result{
7487
Iterations: c.Count,
7588
}
7689

7790
c.StartTimer()
7891
res.Error = c.Bench(ctx, c, c.Count)
7992
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
84107
}
85108

86-
out.Trials++
87-
out.Raw = append(out.Raw, res)
88109
}
89110

90111
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)
91114
if out.HasErrors() {
115+
fmt.Printf(" --- ERRORS: %s\n", strings.Join(out.errReport(), "\n "))
92116
fmt.Printf("--- FAIL: %s (%s)\n", out.Name, out.roundedRuntime())
93117
} else {
94118
fmt.Printf("--- PASS: %s (%s)\n", out.Name, out.roundedRuntime())

benchmark/harness_results.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ func (r *BenchResult) HasErrors() bool {
109109
return *r.hasErrors
110110
}
111111

112+
func (r *BenchResult) errReport() []string {
113+
errs := []string{}
114+
for _, res := range r.Raw {
115+
if res.Error != nil {
116+
errs = append(errs, res.Error.Error())
117+
}
118+
}
119+
return errs
120+
}
121+
112122
type Result struct {
113123
Duration time.Duration
114124
Iterations int

benchmark/multi.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ func MultiFindMany(ctx context.Context, tm TimerManager, iters int) error {
1515
if err != nil {
1616
return err
1717
}
18+
defer db.Client().Disconnect(ctx)
1819

1920
db = db.Client().Database("perftest")
2021
if err = db.Drop(ctx); err != nil {
@@ -28,13 +29,13 @@ func MultiFindMany(ctx context.Context, tm TimerManager, iters int) error {
2829

2930
coll := db.Collection("corpus")
3031

31-
for i := 0; i < iters; i++ {
32-
if _, err = coll.InsertOne(ctx, doc); err != nil {
33-
return err
34-
}
32+
payload := make([]interface{}, iters)
33+
for idx := range payload {
34+
payload[idx] = *doc
35+
}
3536

36-
// TODO: should be remove after resolving GODRIVER-468
37-
_ = doc.Delete("_id")
37+
if _, err = coll.InsertMany(ctx, payload); err != nil {
38+
return err
3839
}
3940

4041
tm.ResetTimer()
@@ -43,14 +44,16 @@ func MultiFindMany(ctx context.Context, tm TimerManager, iters int) error {
4344
if err != nil {
4445
return err
4546
}
47+
defer cursor.Close(ctx)
4648

4749
counter := 0
4850
for cursor.Next(ctx) {
4951
err = cursor.Err()
5052
if err != nil {
5153
return err
5254
}
53-
r, err := cursor.DecodeBytes()
55+
var r bson.Reader
56+
r, err = cursor.DecodeBytes()
5457
if err != nil {
5558
return err
5659
}
@@ -87,6 +90,7 @@ func multiInsertCase(ctx context.Context, tm TimerManager, iters int, data strin
8790
if err != nil {
8891
return err
8992
}
93+
defer db.Client().Disconnect(ctx)
9094

9195
db = db.Client().Database("perftest")
9296
if err = db.Drop(ctx); err != nil {

benchmark/single.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func SingleRunCommand(ctx context.Context, tm TimerManager, iters int) error {
4141
if err != nil {
4242
return err
4343
}
44+
defer db.Client().Disconnect(ctx)
4445

4546
cmd := bson.NewDocument(bson.EC.Boolean("ismaster", true))
4647

@@ -116,6 +117,7 @@ func singleInsertCase(ctx context.Context, tm TimerManager, iters int, data stri
116117
if err != nil {
117118
return err
118119
}
120+
defer db.Client().Disconnect(ctx)
119121

120122
db = db.Client().Database("perftest")
121123
if err = db.Drop(ctx); err != nil {

0 commit comments

Comments
 (0)