Skip to content

Commit 6d135b0

Browse files
miparnisarikarlseguin
authored andcommitted
feat: add benchmarks
1 parent bf904ff commit 6d135b0

File tree

6 files changed

+188
-10
lines changed

6 files changed

+188
-10
lines changed

.github/workflows/master.yaml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Master
2+
on:
3+
push:
4+
branches:
5+
- master
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
bench:
12+
runs-on: ubuntu-latest
13+
timeout-minutes: 15
14+
steps:
15+
- uses: actions/checkout@v3
16+
17+
- uses: actions/setup-go@v4
18+
with:
19+
go-version-file: './go.mod'
20+
21+
- name: Run benchmark and store the output to a file
22+
run: |
23+
set -o pipefail
24+
make bench | tee bench_output.txt
25+
26+
- name: Get benchmark as JSON
27+
uses: benchmark-action/github-action-benchmark@v1
28+
with:
29+
# What benchmark tool the output.txt came from
30+
tool: 'go'
31+
# Where the output from the benchmark tool is stored
32+
output-file-path: bench_output.txt
33+
# Write benchmarks to this file
34+
external-data-json-path: ./cache/benchmark-data.json
35+
# Workflow will fail when an alert happens
36+
fail-on-alert: true
37+
github-token: ${{ secrets.GITHUB_TOKEN }}
38+
comment-on-alert: true
39+
40+
- name: Save benchmark JSON to cache
41+
uses: actions/cache/save@v3
42+
with:
43+
path: ./cache/benchmark-data.json
44+
# Save with commit hash to avoid "cache already exists"
45+
# Save with OS to prevent comparing against results from different CPUs
46+
key: ${{ github.sha }}-${{ runner.os }}-go-benchmark

.github/workflows/pull_request.yaml

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ jobs:
1818
uses: actions/setup-go@v4
1919
with:
2020
go-version-file: './go.mod'
21-
check-latest: true
2221
- name: golangci-lint
2322
uses: golangci/golangci-lint-action@v3
2423
with:
@@ -34,6 +33,75 @@ jobs:
3433
uses: actions/setup-go@v4
3534
with:
3635
go-version-file: './go.mod'
37-
check-latest: true
3836
- name: Unit Tests
39-
run: make t
37+
run: make t
38+
bench:
39+
runs-on: ubuntu-latest
40+
timeout-minutes: 5
41+
steps:
42+
- name: Checkout code
43+
uses: actions/checkout@v3
44+
with:
45+
fetch-depth: 0 # to be able to retrieve the last commit in master branch
46+
47+
- name: Set up Go
48+
uses: actions/setup-go@v4
49+
with:
50+
go-version-file: './go.mod'
51+
cache-dependency-path: './go.sum'
52+
check-latest: true
53+
54+
- name: Run benchmark and store the output to a file
55+
run: |
56+
set -o pipefail
57+
make bench | tee ${{ github.sha }}_bench_output.txt
58+
59+
- name: Get Master branch SHA
60+
id: get-master-branch-sha
61+
run: |
62+
SHA=$(git rev-parse origin/master)
63+
echo "sha=$SHA" >> $GITHUB_OUTPUT
64+
65+
- name: Try to get benchmark JSON from master branch
66+
uses: actions/cache/restore@v3
67+
id: cache
68+
with:
69+
path: ./cache/benchmark-data.json
70+
key: ${{ steps.get-master-branch-sha.outputs.sha }}-${{ runner.os }}-go-benchmark
71+
72+
- name: Compare benchmarks with master
73+
uses: benchmark-action/github-action-benchmark@v1
74+
if: steps.cache.outputs.cache-hit == 'true'
75+
with:
76+
# What benchmark tool the output.txt came from
77+
tool: 'go'
78+
# Where the output from the benchmark tool is stored
79+
output-file-path: ${{ github.sha }}_bench_output.txt
80+
# Where the benchmarks in master are (to compare)
81+
external-data-json-path: ./cache/benchmark-data.json
82+
# Do not save the data
83+
save-data-file: false
84+
# Workflow will fail when an alert happens
85+
fail-on-alert: true
86+
github-token: ${{ secrets.GITHUB_TOKEN }}
87+
# Enable Job Summary for PRs
88+
summary-always: true
89+
90+
- name: Run benchmarks
91+
uses: benchmark-action/github-action-benchmark@v1
92+
if: steps.cache.outputs.cache-hit != 'true'
93+
with:
94+
# What benchmark tool the output.txt came from
95+
tool: 'go'
96+
# Where the output from the benchmark tool is stored
97+
output-file-path: ${{ github.sha }}_bench_output.txt
98+
# Write benchmarks to this file, do not publish to Github Pages
99+
save-data-file: false
100+
external-data-json-path: ./cache/benchmark-data.json
101+
# Workflow will fail when an alert happens
102+
fail-on-alert: true
103+
# Enable alert commit comment
104+
github-token: ${{ secrets.GITHUB_TOKEN }}
105+
comment-on-alert: true
106+
# Enable Job Summary for PRs
107+
summary-always: true

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
vendor/
2+
.idea/
3+
*.out

Makefile

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
.DEFAULT_GOAL := help
2+
3+
.PHONY: help
4+
help:
5+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
6+
7+
.PHONY: bench
8+
bench: ## Run benchmarks
9+
go test ./... -bench . -benchtime 5s -timeout 0 -run=XXX -benchmem
10+
111
.PHONY: l
212
l: ## Lint Go source files
313
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest && golangci-lint run
@@ -12,9 +22,4 @@ f: ## Format code
1222

1323
.PHONY: c
1424
c: ## Measure code coverage
15-
go test -race -covermode=atomic ./... -coverprofile=cover.out && \
16-
go tool cover -func cover.out \
17-
| grep -v '100.0%' \
18-
|| true
19-
20-
rm cover.out
25+
go test -race -covermode=atomic ./... -coverprofile=cover.out

cache_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,63 @@ func Test_ConcurrentClearAndSet(t *testing.T) {
441441
}
442442
}
443443

444+
func BenchmarkFrequentSets(b *testing.B) {
445+
cache := New(Configure[int]())
446+
defer cache.Stop()
447+
448+
b.ResetTimer()
449+
for n := 0; n < b.N; n++ {
450+
key := strconv.Itoa(n)
451+
cache.Set(key, n, time.Minute)
452+
}
453+
}
454+
455+
func BenchmarkFrequentGets(b *testing.B) {
456+
cache := New(Configure[int]())
457+
defer cache.Stop()
458+
numKeys := 500
459+
for i := 0; i < numKeys; i++ {
460+
key := strconv.Itoa(i)
461+
cache.Set(key, i, time.Minute)
462+
}
463+
464+
b.ResetTimer()
465+
for n := 0; n < b.N; n++ {
466+
key := strconv.FormatInt(rand.Int63n(int64(numKeys)), 10)
467+
cache.Get(key)
468+
}
469+
}
470+
471+
func BenchmarkGetWithPromoteSmall(b *testing.B) {
472+
getsPerPromotes := 5
473+
cache := New(Configure[int]().GetsPerPromote(int32(getsPerPromotes)))
474+
defer cache.Stop()
475+
476+
b.ResetTimer()
477+
for n := 0; n < b.N; n++ {
478+
key := strconv.Itoa(n)
479+
cache.Set(key, n, time.Minute)
480+
for i := 0; i < getsPerPromotes; i++ {
481+
cache.Get(key)
482+
}
483+
}
484+
}
485+
486+
func BenchmarkGetWithPromoteLarge(b *testing.B) {
487+
getsPerPromotes := 100
488+
cache := New(Configure[int]().GetsPerPromote(int32(getsPerPromotes)))
489+
defer cache.Stop()
490+
491+
b.ResetTimer()
492+
for n := 0; n < b.N; n++ {
493+
key := strconv.Itoa(n)
494+
cache.Set(key, n, time.Minute)
495+
for i := 0; i < getsPerPromotes; i++ {
496+
cache.Get(key)
497+
}
498+
}
499+
}
500+
444501
type SizedItem struct {
445502
id int
446503
s int64

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/karlseguin/ccache/v3
22

3-
go 1.18
3+
go 1.19

0 commit comments

Comments
 (0)