Skip to content

Commit e49ec13

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 e49ec13

File tree

6 files changed

+148
-0
lines changed

6 files changed

+148
-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: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,43 @@ 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 TEST_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+
Use the variable `TEST_PATH` to set the directory of test files.
64+
It is set to `./...` by default, so it runs all the Benchmark tests in project.
65+
66+
Before calculating performance difference between master and the current branch,
67+
prepare benchmark results of master:
68+
```bash
69+
make perf-reference DURATION=5s COUNT=7 BENCH_PATH=custom_path TEST_PATH=.
70+
```
71+
72+
To measure performance degradation after changes in code, firstly call `make bench`
73+
and `perf-reference` and then run:
74+
```bash
75+
make perf-diff BENCH_PATH=custom_path
76+
```
77+
4178
## Code review checklist
4279

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

Makefile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,33 @@ 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+
TEST_PATH ?= ./...
63+
64+
.PHONY: bench-deps
65+
bench-deps:
66+
rm -rf ${BENCH_PATH}
67+
mkdir ${BENCH_PATH}
68+
go clean -testcache
69+
cd ${BENCH_PATH} && git clone https://go.googlesource.com/perf && cd perf && go install ./cmd/benchstat
70+
rm -rf ${BENCH_PATH}/perf
71+
72+
.PHONY: bench
73+
bench:
74+
go test ${TEST_PATH} -bench=. -run=^Benchmark -benchmem -benchtime=${DURATION} -count=${COUNT} 2>&1 \
75+
| grep -v pkg: | grep -v ok | grep -v ? | tee ${BENCH_PATH}/bench.txt
76+
benchstat ${BENCH_PATH}/bench.txt
77+
78+
.PHONY: perf-reference
79+
perf-reference:
80+
cd ${BENCH_PATH} && git clone https://github.com/tarantool/go-tarantool.git
81+
cd ${BENCH_PATH}/go-tarantool && go test ${TESTS_PATH} -bench=. -run=^Benchmark -benchmem -benchtime=${DURATION} \
82+
-count=${COUNT} 2>&1 | grep -v pkg: | grep -v ok | grep -v ? | tee ../reference.txt
83+
rm -rf ${BENCH_PATH}/go-tarantool
84+
85+
.PHONY: perf-diff
86+
perf-diff:
87+
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)