Skip to content

Commit 557877c

Browse files
committed
feat: add benchmark for store with different connection settings
1 parent f6e4e50 commit 557877c

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

store/test/store_bench_test.go

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package teststore
2+
3+
import (
4+
"context"
5+
"runtime"
6+
"testing"
7+
"time"
8+
9+
"github.com/lithammer/shortuuid/v4"
10+
"github.com/usememos/memos/store"
11+
)
12+
13+
// BenchmarkDB groups all database benchmarks
14+
func BenchmarkDB(b *testing.B) {
15+
b.Run("BenchmarkDBConnPool", BenchmarkDBConnPool)
16+
}
17+
18+
// benchmarkConfig defines the configuration for benchmark testing
19+
type benchmarkConfig struct {
20+
maxOpenConns int
21+
maxIdleConns int
22+
connMaxLifetime *time.Duration
23+
}
24+
25+
// benchmarkConnectionPool tests the performance of sql.DB connection pooling.
26+
func BenchmarkDBConnPool(b *testing.B) {
27+
cores := runtime.NumCPU()
28+
lifeTime := time.Hour
29+
cases := []struct {
30+
name string
31+
config benchmarkConfig
32+
}{
33+
{
34+
name: "default_unlimited",
35+
config: benchmarkConfig{
36+
maxOpenConns: 0, // Use default value 0 (unlimited)
37+
maxIdleConns: 2, // Use default value 2
38+
connMaxLifetime: nil, // Use default value 0 (unlimited)
39+
},
40+
},
41+
{
42+
name: "max_conns_equals_cores",
43+
config: benchmarkConfig{
44+
maxOpenConns: cores,
45+
maxIdleConns: cores / 2,
46+
connMaxLifetime: &lifeTime,
47+
},
48+
},
49+
{
50+
name: "max_conns_double_cores",
51+
config: benchmarkConfig{
52+
maxOpenConns: cores * 2,
53+
maxIdleConns: cores,
54+
connMaxLifetime: &lifeTime,
55+
},
56+
},
57+
{
58+
name: "max_conns_25",
59+
config: benchmarkConfig{
60+
maxOpenConns: 25,
61+
maxIdleConns: 10,
62+
connMaxLifetime: &lifeTime,
63+
},
64+
},
65+
{
66+
name: "max_conns_50",
67+
config: benchmarkConfig{
68+
maxOpenConns: 50,
69+
maxIdleConns: 25,
70+
connMaxLifetime: &lifeTime,
71+
},
72+
},
73+
{
74+
name: "max_conns_100",
75+
config: benchmarkConfig{
76+
maxOpenConns: 100,
77+
maxIdleConns: 50,
78+
connMaxLifetime: &lifeTime,
79+
},
80+
},
81+
}
82+
83+
for _, tc := range cases {
84+
b.Run(tc.name, func(b *testing.B) {
85+
ctx := context.Background()
86+
ts := NewTestingStore(ctx, &testing.T{})
87+
db := ts.GetDriver().GetDB()
88+
89+
db.SetMaxOpenConns(tc.config.maxOpenConns)
90+
db.SetMaxIdleConns(tc.config.maxIdleConns)
91+
92+
if tc.config.connMaxLifetime != nil {
93+
db.SetConnMaxLifetime(*tc.config.connMaxLifetime)
94+
}
95+
96+
user, err := createTestingHostUser(ctx, ts)
97+
if err != nil {
98+
b.Logf("failed to create testing host user: %v", err)
99+
}
100+
101+
// Set concurrency level
102+
b.SetParallelism(100)
103+
b.ResetTimer()
104+
105+
// Record initial stats
106+
startStats := db.Stats()
107+
108+
b.RunParallel(func(pb *testing.PB) {
109+
for pb.Next() {
110+
// Execute database operation
111+
memoCreate := &store.Memo{
112+
UID: shortuuid.New(),
113+
CreatorID: user.ID,
114+
Content: "test_content",
115+
Visibility: store.Public,
116+
}
117+
_, err := ts.CreateMemo(ctx, memoCreate)
118+
if err != nil {
119+
b.Fatal("failed to create memo:", err)
120+
}
121+
}
122+
})
123+
124+
// Collect and report connection pool statistics
125+
endStats := db.Stats()
126+
// b.ReportMetric(float64(endStats.MaxOpenConnections), "max_open_conns")
127+
// b.ReportMetric(float64(endStats.InUse), "conns_in_use")
128+
// b.ReportMetric(float64(endStats.Idle), "idle_conns")
129+
b.ReportMetric(float64(endStats.WaitCount-startStats.WaitCount), "wait_count")
130+
b.ReportMetric(float64((endStats.WaitDuration - startStats.WaitDuration).Milliseconds()), "wait_duration_ms")
131+
})
132+
}
133+
}

0 commit comments

Comments
 (0)