1// Copyright 2019 The Go Cloud Development Kit Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package drivertest
16
17import (
18	"context"
19	"fmt"
20	"strconv"
21	"sync/atomic"
22	"testing"
23
24	"gocloud.dev/docstore"
25)
26
27// RunBenchmarks runs benchmarks for docstore drivers.
28func RunBenchmarks(b *testing.B, coll *docstore.Collection) {
29	defer coll.Close()
30	clearCollection(b, coll)
31	b.Run("BenchmarkSingleActionPut", func(b *testing.B) {
32		benchmarkSingleActionPut(10, b, coll)
33	})
34	b.Run("BenchmarkSingleActionGet", func(b *testing.B) {
35		benchmarkSingleActionGet(10, b, coll)
36	})
37	b.Run("BenchmarkActionListPut", func(b *testing.B) {
38		benchmarkActionListPut(50, b, coll)
39	})
40	b.Run("BenchmarkActionListGet", func(b *testing.B) {
41		benchmarkActionListGet(100, b, coll)
42	})
43	clearCollection(b, coll)
44}
45
46func benchmarkSingleActionPut(n int, b *testing.B, coll *docstore.Collection) {
47	ctx := context.Background()
48	const baseKey = "benchmarksingleaction-put-"
49	var nextID uint32
50
51	b.ResetTimer()
52	b.RunParallel(func(pb *testing.PB) {
53		for pb.Next() {
54			for i := 0; i < n; i++ {
55				key := fmt.Sprintf("%s%d", baseKey, atomic.AddUint32(&nextID, 1))
56				doc := docmap{KeyField: key, "S": key}
57				if err := coll.Put(ctx, doc); err != nil {
58					b.Error(err)
59				}
60			}
61		}
62	})
63}
64
65func benchmarkSingleActionGet(n int, b *testing.B, coll *docstore.Collection) {
66	ctx := context.Background()
67	const baseKey = "benchmarksingleaction-get-"
68	docs := make([]docmap, n)
69	puts := coll.Actions()
70	for i := 0; i < n; i++ {
71		docs[i] = docmap{KeyField: baseKey + strconv.Itoa(i), "n": i}
72		puts.Put(docs[i])
73	}
74	if err := puts.Do(ctx); err != nil {
75		b.Fatal(err)
76	}
77
78	b.ResetTimer()
79	b.RunParallel(func(pb *testing.PB) {
80		for pb.Next() {
81			for _, doc := range docs {
82				got := docmap{KeyField: doc[KeyField]}
83				if err := coll.Get(ctx, got); err != nil {
84					b.Fatal(err)
85				}
86			}
87		}
88	})
89}
90
91func benchmarkActionListPut(n int, b *testing.B, coll *docstore.Collection) {
92	ctx := context.Background()
93	const baseKey = "benchmarkactionlist-put-"
94	var nextID uint32
95
96	b.ResetTimer()
97	b.RunParallel(func(pb *testing.PB) {
98		for pb.Next() {
99			actions := coll.Actions()
100			for i := 0; i < n; i++ {
101				key := fmt.Sprintf("%s%d", baseKey, atomic.AddUint32(&nextID, 1))
102				doc := docmap{KeyField: key, "S": key}
103				actions.Put(doc)
104			}
105			if err := actions.Do(ctx); err != nil {
106				b.Error(err)
107			}
108		}
109	})
110}
111
112func benchmarkActionListGet(n int, b *testing.B, coll *docstore.Collection) {
113	ctx := context.Background()
114	const baseKey = "benchmarkactionlist-get-"
115	docs := make([]docmap, n)
116	puts := coll.Actions()
117	for i := 0; i < n; i++ {
118		docs[i] = docmap{KeyField: baseKey + strconv.Itoa(i), "n": i}
119		puts.Put(docs[i])
120	}
121	if err := puts.Do(ctx); err != nil {
122		b.Fatal(err)
123	}
124
125	b.ResetTimer()
126	b.RunParallel(func(pb *testing.PB) {
127		for pb.Next() {
128			gets := coll.Actions()
129			for _, doc := range docs {
130				got := docmap{KeyField: doc[KeyField]}
131				gets.Get(got)
132			}
133			if err := gets.Do(ctx); err != nil {
134				b.Fatal(err)
135			}
136		}
137	})
138}
139