Skip to content

Commit a00a782

Browse files
committed
test(benchmark): initial benchmarks for ledger and database
Signed-off-by: Chris Gianelloni <wolf31o2@blinklabs.io>
1 parent 1819090 commit a00a782

File tree

8 files changed

+1778
-4
lines changed

8 files changed

+1778
-4
lines changed

.github/workflows/go-test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ jobs:
2727
go-version: ${{ matrix.go-version }}
2828
- name: go-test
2929
run: go test ./...
30+
- name: go-bench
31+
run: go test -bench=. -benchmem ./...

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,19 @@ golines:
4343
test: mod-tidy
4444
go test -v -race ./...
4545

46+
bench: mod-tidy
47+
go test -bench=. -benchmem ./...
48+
4649
test-load:
4750
rm -rf .dingo
4851
go run ./cmd/dingo load database/immutable/testdata
4952

53+
test-load-profile:
54+
rm -rf .dingo dingo
55+
go build -o dingo ./cmd/dingo
56+
./dingo --cpuprofile=cpu.prof --memprofile=mem.prof load database/immutable/testdata
57+
@echo "Profiling complete. Run 'go tool pprof cpu.prof' or 'go tool pprof mem.prof' to analyze"
58+
5059
# Build our program binaries
5160
# Depends on GO_FILES to determine when rebuild is needed
5261
$(BINARIES): mod-tidy $(GO_FILES)

cmd/dingo/main.go

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818
"fmt"
1919
"log/slog"
2020
"os"
21+
"runtime/pprof"
22+
"strings"
2123

2224
"github.com/blinklabs-io/dingo/internal/config"
2325
"github.com/blinklabs-io/dingo/internal/version"
@@ -37,7 +39,9 @@ func slogPrintf(format string, v ...any) {
3739

3840
var (
3941
globalFlags = struct {
40-
debug bool
42+
cpuprofile string
43+
memprofile string
44+
debug bool
4145
}{}
4246
configFile string
4347
)
@@ -72,6 +76,37 @@ func commonRun() *slog.Logger {
7276
}
7377

7478
func main() {
79+
// Parse profiling flags before cobra setup
80+
cpuprofile := ""
81+
memprofile := ""
82+
for _, arg := range os.Args {
83+
if after, ok := strings.CutPrefix(arg, "--cpuprofile="); ok {
84+
cpuprofile = after
85+
}
86+
if after, ok := strings.CutPrefix(arg, "--memprofile="); ok {
87+
memprofile = after
88+
}
89+
}
90+
91+
// Initialize CPU profiling (starts immediately, stops on exit)
92+
if cpuprofile != "" {
93+
fmt.Fprintf(os.Stderr, "Starting CPU profiling to %s\n", cpuprofile)
94+
f, err := os.Create(cpuprofile)
95+
if err != nil {
96+
fmt.Fprintf(os.Stderr, "could not create CPU profile: %v\n", err)
97+
os.Exit(1)
98+
}
99+
defer f.Close()
100+
if err := pprof.StartCPUProfile(f); err != nil {
101+
fmt.Fprintf(os.Stderr, "could not start CPU profile: %v\n", err)
102+
os.Exit(1)
103+
}
104+
defer func() {
105+
pprof.StopCPUProfile()
106+
fmt.Fprintf(os.Stderr, "CPU profiling stopped\n")
107+
}()
108+
}
109+
75110
rootCmd := &cobra.Command{
76111
Use: programName,
77112
Run: func(cmd *cobra.Command, args []string) {
@@ -89,6 +124,10 @@ func main() {
89124
BoolVarP(&globalFlags.debug, "debug", "D", false, "enable debug logging")
90125
rootCmd.PersistentFlags().
91126
StringVar(&configFile, "config", "", "path to config file")
127+
rootCmd.PersistentFlags().
128+
StringVar(&globalFlags.cpuprofile, "cpuprofile", "", "write cpu profile to file")
129+
rootCmd.PersistentFlags().
130+
StringVar(&globalFlags.memprofile, "memprofile", "", "write memory profile to file")
92131

93132
rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
94133
cfg, err := config.LoadConfig(configFile)
@@ -109,4 +148,19 @@ func main() {
109148
// NOTE: we purposely don't display the error, since cobra will have already displayed it
110149
os.Exit(1)
111150
}
151+
152+
// Finalize memory profiling (captures heap state at program end)
153+
if memprofile != "" {
154+
f, err := os.Create(memprofile)
155+
if err != nil {
156+
fmt.Fprintf(os.Stderr, "could not create memory profile: %v\n", err)
157+
os.Exit(1)
158+
}
159+
defer f.Close()
160+
if err := pprof.WriteHeapProfile(f); err != nil {
161+
fmt.Fprintf(os.Stderr, "could not write memory profile: %v\n", err)
162+
os.Exit(1)
163+
}
164+
fmt.Fprintf(os.Stderr, "Memory profiling complete\n")
165+
}
112166
}

database/benchmark_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2025 Blink Labs Software
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+
// http://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+
15+
package database
16+
17+
import (
18+
"testing"
19+
)
20+
21+
// BenchmarkTransactionCreate benchmarks creating a read-only transaction
22+
func BenchmarkTransactionCreate(b *testing.B) {
23+
// Create a temporary database
24+
config := &Config{
25+
DataDir: "", // In-memory
26+
}
27+
db, err := New(config)
28+
if err != nil {
29+
b.Fatal(err)
30+
}
31+
defer db.Close()
32+
33+
for b.Loop() {
34+
txn := db.Transaction(false)
35+
_ = txn
36+
}
37+
}

database/plugin/blob/aws/commit_timestamp.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ func (b *BlobStoreS3) GetCommitTimestamp(ctx context.Context) (int64, error) {
3838
err,
3939
)
4040
if migrateErr := b.SetCommitTimestamp(ctx, ts); migrateErr != nil {
41-
b.logger.Errorf("failed to migrate plaintext commit timestamp: %v", migrateErr)
41+
b.logger.Errorf(
42+
"failed to migrate plaintext commit timestamp: %v",
43+
migrateErr,
44+
)
4245
}
4346
return ts, nil
4447
}

database/plugin/blob/gcs/commit_timestamp.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ func (b *BlobStoreGCS) GetCommitTimestamp(ctx context.Context) (int64, error) {
4848
err,
4949
)
5050
if migrateErr := b.SetCommitTimestamp(ctx, ts); migrateErr != nil {
51-
b.logger.Errorf("failed to migrate plaintext commit timestamp: %v", migrateErr)
51+
b.logger.Errorf(
52+
"failed to migrate plaintext commit timestamp: %v",
53+
migrateErr,
54+
)
5255
}
5356
return ts, nil
5457
}

database/plugin/metadata/sqlite/transaction.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func saveAccountIfNew(account *models.Account, txn *gorm.DB) error {
105105
}
106106

107107
// saveCertRecord saves a certificate record and returns any error
108-
func saveCertRecord(record interface{}, txn *gorm.DB) error {
108+
func saveCertRecord(record any, txn *gorm.DB) error {
109109
result := txn.Create(record)
110110
return result.Error
111111
}

0 commit comments

Comments
 (0)