Skip to content

Commit

Permalink
GODRIVER-115: multi document benchmarks
Browse files Browse the repository at this point in the history
Change-Id: I0d73d3ae90bfd1286f2dfd158bea31e8873c5988
  • Loading branch information
Sam Kleinman committed Jun 22, 2018
1 parent 59e0104 commit 75948c7
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ buildvariants:
- name: perf
display_name: "Performance"
run_on:
- ubuntu1604-test
- ubuntu1604-build
expansions:
GO_DIST: "/opt/golang/go1.9"
tasks:
Expand Down
18 changes: 18 additions & 0 deletions benchmark/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,5 +203,23 @@ func getAllCases() []*CaseDefinition {
Size: 27310890,
Runtime: StandardRuntime,
},
{
Bench: MultiFindMany,
Count: tenThousand,
Size: 16220000,
Runtime: StandardRuntime,
},
{
Bench: MultiInsertSmallDocument,
Count: tenThousand,
Size: 2750000,
Runtime: StandardRuntime,
},
{
Bench: MultiInsertLargeDocument,
Count: ten,
Size: 27310890,
Runtime: StandardRuntime,
},
}
}
15 changes: 9 additions & 6 deletions benchmark/harness_case.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@ func (c *CaseDefinition) StopTimer() {
if c.startAt.IsZero() {
return
}

c.startAt = time.Time{}
c.Runtime += time.Since(c.startAt)
c.startAt = time.Time{}
}

func (c *CaseDefinition) roundedRuntime() time.Duration {
return roundDurationMS(c.Runtime)
}

func (c *CaseDefinition) Run(ctx context.Context) *BenchResult {
Expand All @@ -58,6 +61,7 @@ func (c *CaseDefinition) Run(ctx context.Context) *BenchResult {

fmt.Println("=== RUN", out.Name)
c.startAt = time.Now()

for {
if time.Since(c.startAt) > c.Runtime {
if out.Trials >= MinIterations {
Expand All @@ -66,10 +70,10 @@ func (c *CaseDefinition) Run(ctx context.Context) *BenchResult {
break
}
}

res := Result{
Iterations: c.Count,
}

c.StartTimer()
res.Error = c.Bench(ctx, c, c.Count)
c.StopTimer()
Expand All @@ -85,9 +89,9 @@ func (c *CaseDefinition) Run(ctx context.Context) *BenchResult {

out.Duration = out.totalDuration()
if out.HasErrors() {
fmt.Printf("--- FAIL: %s (%s)\n", out.Name, out.Duration.Round(time.Millisecond))
fmt.Printf("--- FAIL: %s (%s)\n", out.Name, out.roundedRuntime())
} else {
fmt.Printf("--- PASS: %s (%s)\n", out.Name, out.Duration.Round(time.Millisecond))
fmt.Printf("--- PASS: %s (%s)\n", out.Name, out.roundedRuntime())
}

return out
Expand All @@ -100,7 +104,6 @@ func (c *CaseDefinition) String() string {
}

func (c *CaseDefinition) Name() string { return getName(c.Bench) }

func getName(i interface{}) string {
n := runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
parts := strings.Split(n, ".")
Expand Down
13 changes: 11 additions & 2 deletions benchmark/harness_results.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,15 @@ func (r *BenchResult) timings() []float64 {

func (r *BenchResult) totalDuration() time.Duration {
var out time.Duration
for _, r := range r.Raw {
out += r.Duration
for _, trial := range r.Raw {
out += trial.Duration
}
return out
}

func (r *BenchResult) adjustResults(data float64) float64 { return float64(r.DataSize) / data }
func (r *BenchResult) getThroughput(data float64) float64 { return float64(r.Operations) / data }
func (r *BenchResult) roundedRuntime() time.Duration { return roundDurationMS(r.Duration) }

func (r *BenchResult) String() string {
return fmt.Sprintf("name=%s, trials=%d, secs=%s", r.Name, r.Trials, r.Duration)
Expand All @@ -113,3 +114,11 @@ type Result struct {
Iterations int
Error error
}

func roundDurationMS(d time.Duration) time.Duration {
rounded := d.Round(time.Millisecond)
if rounded == 1<<63-1 {
return 0
}
return rounded
}
137 changes: 137 additions & 0 deletions benchmark/multi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package benchmark

import (
"context"
"errors"

"github.com/mongodb/mongo-go-driver/bson"
)

func MultiFindMany(ctx context.Context, tm TimerManager, iters int) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()

db, err := getClientDB(ctx)
if err != nil {
return err
}

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

doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, singleAndMultiDataDir, tweetData)
if err != nil {
return err
}

coll := db.Collection("corpus")

for i := 0; i < iters; i++ {
if _, err = coll.InsertOne(ctx, doc); err != nil {
return err
}

// TODO: should be remove after resolving GODRIVER-468
_ = doc.Delete("_id")
}

tm.ResetTimer()

cursor, err := coll.Find(ctx, bson.NewDocument())
if err != nil {
return err
}

counter := 0
for cursor.Next(ctx) {
err = cursor.Err()
if err != nil {
return err
}
r, err := cursor.DecodeBytes()
if err != nil {
return err
}
if len(r) == 0 {
return errors.New("error retrieving document")
}

counter++
}

if counter != iters {
return errors.New("problem iterating cursors")

}

tm.StopTimer()

if err = cursor.Close(ctx); err != nil {
return err
}

if err = db.Drop(ctx); err != nil {
return err
}

return nil
}

func multiInsertCase(ctx context.Context, tm TimerManager, iters int, data string) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()

db, err := getClientDB(ctx)
if err != nil {
return err
}

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

doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, singleAndMultiDataDir, data)
if err != nil {
return err
}

_, err = db.RunCommand(ctx, bson.NewDocument(bson.EC.String("create", "corpus")))
if err != nil {
return err
}

payload := make([]interface{}, iters)
for idx := range payload {
payload[idx] = *doc
}

coll := db.Collection("corpus")

tm.ResetTimer()
res, err := coll.InsertMany(ctx, payload)
if err != nil {
return err
}
tm.StopTimer()

if len(res.InsertedIDs) != iters {
return errors.New("bulk operation did not complete")
}

if err = db.Drop(ctx); err != nil {
return err
}

return nil
}

func MultiInsertSmallDocument(ctx context.Context, tm TimerManager, iters int) error {
return multiInsertCase(ctx, tm, iters, smallData)
}

func MultiInsertLargeDocument(ctx context.Context, tm TimerManager, iters int) error {
return multiInsertCase(ctx, tm, iters, largeData)
}
7 changes: 7 additions & 0 deletions benchmark/multi_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package benchmark

import "testing"

func BenchmarkMultiFindMany(b *testing.B) { WrapCase(MultiFindMany)(b) }
func BenchmarkMultiInsertSmallDocument(b *testing.B) { WrapCase(MultiInsertSmallDocument)(b) }
func BenchmarkMultiInsertLargeDocument(b *testing.B) { WrapCase(MultiInsertLargeDocument)(b) }

0 comments on commit 75948c7

Please sign in to comment.