Skip to content

Commit 3c4a343

Browse files
committed
test: add benchmark tests
Added benchmarks of large Select and Replace. Added a new target in Makefile for running benchmark tests. Added a new space in config.lua for large Select tests. Added a new target in Makefile for measuring performance degradation between current changes and master. Added a new line in gitignore for ignoring artifacts from bench target. Added a new step for running benchmark tests in ci. Added description to the CONTRIBUTING.md for how to run benchmark tests. Closes #122
1 parent 34b9d0e commit 3c4a343

File tree

6 files changed

+142
-0
lines changed

6 files changed

+142
-0
lines changed

.github/workflows/testing.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,6 @@ jobs:
6363
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6464
run: |
6565
make coveralls
66+
67+
- name: Check workability of benchmark tests
68+
run: make bench-deps bench DURATION=1x COUNT=1

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
.idea/
44
work_dir*
55
.rocks
6+
bench

CONTRIBUTING.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,40 @@ For example, for running tests in `multi`, `uuid` and `main` packages, call
3838
make test-multi test-uuid test-main
3939
```
4040

41+
Before running benchmark or measuring performance degradation, install benchmark dependencies:
42+
```bash
43+
make bench-deps BENCH_PATH=custom_path
44+
```
45+
46+
Use the variable `BENCH_PATH` to specialize the path of benchmark artifacts.
47+
It is set to `bench` by default.
48+
49+
To run benchmark tests, call:
50+
```bash
51+
make bench DURATION=5s COUNT=7 BENCH_PATH=custom_path
52+
```
53+
54+
Use the variable `DURATION` to set the duration of perf tests. That variable is mapped on
55+
testing [flag](https://pkg.go.dev/cmd/go#hdr-Testing_flags) `-benchtime` for gotest.
56+
It may take the values in seconds (e.g, `5s`) or count of iterations (e.g, `1000x`).
57+
It is set to `3s` by default.
58+
59+
Use the variable `COUNT` to control the count of benchmark runs for each test. It is set to `5` by default.
60+
That variable is mapped on testing flag `-count`.
61+
Use higher values if the benchmark numbers aren't stable.
62+
63+
Before calculating performance difference between master and the current branch,
64+
prepare benchmark results of master:
65+
```bash
66+
make perf-reference DURATION=5s COUNT=7 BENCH_PATH=custom_path
67+
```
68+
69+
To measure performance degradation after changes in code, firstly call `make bench`
70+
and `perf-reference` and then run:
71+
```bash
72+
make perf-diff BENCH_PATH=custom_path
73+
```
74+
4175
## Code review checklist
4276

4377
- Public API contains functions, variables, constants that are needed from

Makefile

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,30 @@ coverage:
5555
coveralls: coverage
5656
go get github.com/mattn/goveralls
5757
goveralls -coverprofile=$(COVERAGE_FILE) -service=github
58+
59+
DURATION ?= 3s
60+
COUNT ?= 5
61+
BENCH_PATH ?= bench
62+
63+
.PHONY: bench-deps
64+
bench-deps:
65+
rm -rf ${BENCH_PATH}
66+
mkdir ${BENCH_PATH}
67+
go clean -testcache
68+
cd ${BENCH_PATH} && git clone https://go.googlesource.com/perf && cd perf && go install ./cmd/benchstat
69+
rm -rf ${BENCH_PATH}/perf
70+
71+
.PHONY: bench
72+
bench:
73+
go test -bench=. -benchmem -benchtime=${DURATION} -count=${COUNT} 2>&1 | tee ${BENCH_PATH}/bench.txt
74+
benchstat ${BENCH_PATH}/bench.txt
75+
76+
.PHONY: perf-reference
77+
perf-reference:
78+
cd ${BENCH_PATH} && git clone https://github.com/tarantool/go-tarantool.git
79+
cd ${BENCH_PATH}/go-tarantool && go test -bench=. -benchmem -benchtime=${DURATION} -count=${COUNT} 2>&1 | tee ../reference.txt
80+
rm -rf ${BENCH_PATH}/go-tarantool
81+
82+
.PHONY: perf-diff
83+
perf-diff:
84+
benchstat ${BENCH_PATH}/reference.txt ${BENCH_PATH}/bench.txt

config.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,31 @@ box.once("init", function()
4040
})
4141
st:truncate()
4242

43+
local s2 = box.schema.space.create('test_perf', {
44+
id = 520,
45+
temporary = true,
46+
if_not_exists = true,
47+
field_count = 3,
48+
format = {
49+
{name = "id", type = "unsigned"},
50+
{name = "name", type = "string"},
51+
{name = "arr1", type = "array"},
52+
},
53+
})
54+
s2:create_index('primary', {type = 'tree', unique = true, parts = {1, 'unsigned'}, if_not_exists = true})
55+
s2:create_index('secondary', {id = 5, type = 'tree', unique = false, parts = {2, 'string'}, if_not_exists = true})
56+
local arr_data = {}
57+
for i = 1,100 do
58+
arr_data[i] = i
59+
end
60+
for i = 1,1000 do
61+
s2:insert{
62+
i,
63+
'test_name',
64+
arr_data,
65+
}
66+
end
67+
4368
--box.schema.user.grant('guest', 'read,write,execute', 'universe')
4469
box.schema.func.create('box.info')
4570
box.schema.func.create('simple_incr')
@@ -49,6 +74,7 @@ box.once("init", function()
4974
box.schema.user.grant('test', 'execute', 'universe')
5075
box.schema.user.grant('test', 'read,write', 'space', 'test')
5176
box.schema.user.grant('test', 'read,write', 'space', 'schematest')
77+
box.schema.user.grant('test', 'read,write', 'space', 'test_perf')
5278
end)
5379

5480
local function func_name()

tarantool_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,57 @@ func BenchmarkClientParallelMassiveUntyped(b *testing.B) {
363363
close(limit)
364364
}
365365

366+
func BenchmarkConnection_Replace(b *testing.B) {
367+
conn, err := Connect(server, opts)
368+
if err != nil {
369+
b.Errorf("No connection available")
370+
return
371+
}
372+
defer conn.Close()
373+
spaceNo = 520
374+
375+
rSpaceNo, _, err := conn.Schema.ResolveSpaceIndex("test_perf", "secondary")
376+
if err != nil {
377+
b.Fatalf("Space is not resolved: %s", err.Error())
378+
}
379+
380+
b.ResetTimer()
381+
b.RunParallel(func(pb *testing.PB) {
382+
for pb.Next() {
383+
_, err := conn.Replace(rSpaceNo, []interface{}{uint(1), "hello", []interface{}{}})
384+
if err != nil {
385+
b.Error(err)
386+
}
387+
}
388+
})
389+
}
390+
391+
func BenchmarkConnection_LargeSelect(b *testing.B) {
392+
conn, err := Connect(server, opts)
393+
if err != nil {
394+
b.Errorf("No connection available")
395+
return
396+
}
397+
defer conn.Close()
398+
399+
schema := conn.Schema
400+
rSpaceNo, rIndexNo, err := schema.ResolveSpaceIndex("test_perf", "secondary")
401+
if err != nil {
402+
b.Fatalf("symbolic space and index params not resolved")
403+
}
404+
405+
offset, limit := uint32(0), uint32(1000)
406+
b.ResetTimer()
407+
b.RunParallel(func(pb *testing.PB) {
408+
for pb.Next() {
409+
_, err := conn.Select(rSpaceNo, rIndexNo, offset, limit, IterEq, []interface{}{"test_name"})
410+
if err != nil {
411+
b.Fatal(err)
412+
}
413+
}
414+
})
415+
}
416+
366417
///////////////////
367418

368419
func TestClient(t *testing.T) {

0 commit comments

Comments
 (0)