Skip to content

Commit 4a95081

Browse files
committed
add BenchmarkReceive10kRowsCompress (go-sql-driver#1704)
* Rename BenchmarkReceiveMassiveRows to BenchmarkReceive10kRows * Add BenchmarkReceive10kRowsCompress that run BenchmarkReceiveMassiveRows with compression * Other tiny benchmark improvements.
1 parent 1bee809 commit 4a95081

File tree

2 files changed

+54
-29
lines changed

2 files changed

+54
-29
lines changed

.github/workflows/test.yml

+4
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ jobs:
9696
run: |
9797
go test -v '-race' '-covermode=atomic' '-coverprofile=coverage.out' -parallel 10
9898
99+
- name: benchmark
100+
run: |
101+
go test -run '^$' -bench .
102+
99103
- name: Send coverage
100104
uses: shogo82148/actions-goveralls@v1
101105
with:

benchmark_test.go

+50-29
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ func (tb *TB) checkStmt(stmt *sql.Stmt, err error) *sql.Stmt {
4646
return stmt
4747
}
4848

49-
func initDB(b *testing.B, useCompression bool, queries ...string) *sql.DB {
49+
func initDB(b *testing.B, compress bool, queries ...string) *sql.DB {
5050
tb := (*TB)(b)
5151
comprStr := ""
52-
if useCompression {
52+
if compress {
5353
comprStr = "&compress=1"
5454
}
5555
db := tb.checkDB(sql.Open(driverNameTest, dsn+comprStr))
@@ -64,16 +64,15 @@ func initDB(b *testing.B, useCompression bool, queries ...string) *sql.DB {
6464
const concurrencyLevel = 10
6565

6666
func BenchmarkQuery(b *testing.B) {
67-
benchmarkQueryHelper(b, false)
67+
benchmarkQuery(b, false)
6868
}
6969

70-
func BenchmarkQueryCompression(b *testing.B) {
71-
benchmarkQueryHelper(b, true)
70+
func BenchmarkQueryCompressed(b *testing.B) {
71+
benchmarkQuery(b, true)
7272
}
7373

74-
func benchmarkQueryHelper(b *testing.B, compr bool) {
74+
func benchmarkQuery(b *testing.B, compr bool) {
7575
tb := (*TB)(b)
76-
b.StopTimer()
7776
b.ReportAllocs()
7877
db := initDB(b, compr,
7978
"DROP TABLE IF EXISTS foo",
@@ -115,8 +114,6 @@ func benchmarkQueryHelper(b *testing.B, compr bool) {
115114

116115
func BenchmarkExec(b *testing.B) {
117116
tb := (*TB)(b)
118-
b.StopTimer()
119-
b.ReportAllocs()
120117
db := tb.checkDB(sql.Open(driverNameTest, dsn))
121118
db.SetMaxIdleConns(concurrencyLevel)
122119
defer db.Close()
@@ -128,9 +125,17 @@ func BenchmarkExec(b *testing.B) {
128125
var wg sync.WaitGroup
129126
wg.Add(concurrencyLevel)
130127
defer wg.Wait()
131-
b.StartTimer()
132128

129+
<<<<<<< HEAD
133130
for i := 0; i < concurrencyLevel; i++ {
131+
||||||| parent of f7d94ec (add BenchmarkReceive10kRowsCompress (#1704))
132+
for range concurrencyLevel {
133+
=======
134+
b.ReportAllocs()
135+
b.ResetTimer()
136+
137+
for i := 0; i < concurrencyLevel; i++ {
138+
>>>>>>> f7d94ec (add BenchmarkReceive10kRowsCompress (#1704))
134139
go func() {
135140
for {
136141
if atomic.AddInt64(&remain, -1) < 0 {
@@ -158,14 +163,15 @@ func initRoundtripBenchmarks() ([]byte, int, int) {
158163
}
159164

160165
func BenchmarkRoundtripTxt(b *testing.B) {
161-
b.StopTimer()
162166
sample, min, max := initRoundtripBenchmarks()
163167
sampleString := string(sample)
164-
b.ReportAllocs()
165168
tb := (*TB)(b)
166169
db := tb.checkDB(sql.Open(driverNameTest, dsn))
167170
defer db.Close()
168-
b.StartTimer()
171+
172+
b.ReportAllocs()
173+
b.ResetTimer()
174+
169175
var result string
170176
for i := 0; i < b.N; i++ {
171177
length := min + i
@@ -192,15 +198,15 @@ func BenchmarkRoundtripTxt(b *testing.B) {
192198
}
193199

194200
func BenchmarkRoundtripBin(b *testing.B) {
195-
b.StopTimer()
196201
sample, min, max := initRoundtripBenchmarks()
197-
b.ReportAllocs()
198202
tb := (*TB)(b)
199203
db := tb.checkDB(sql.Open(driverNameTest, dsn))
200204
defer db.Close()
201205
stmt := tb.checkStmt(db.Prepare("SELECT ?"))
202206
defer stmt.Close()
203-
b.StartTimer()
207+
208+
b.ReportAllocs()
209+
b.ResetTimer()
204210
var result sql.RawBytes
205211
for i := 0; i < b.N; i++ {
206212
length := min + i
@@ -385,10 +391,9 @@ func BenchmarkQueryRawBytes(b *testing.B) {
385391
}
386392
}
387393

388-
// BenchmarkReceiveMassiveRows measures performance of receiving large number of rows.
389-
func BenchmarkReceiveMassiveRows(b *testing.B) {
394+
func benchmark10kRows(b *testing.B, compress bool) {
390395
// Setup -- prepare 10000 rows.
391-
db := initDB(b, false,
396+
db := initDB(b, compress,
392397
"DROP TABLE IF EXISTS foo",
393398
"CREATE TABLE foo (id INT PRIMARY KEY, val TEXT)")
394399
defer db.Close()
@@ -399,11 +404,14 @@ func BenchmarkReceiveMassiveRows(b *testing.B) {
399404
b.Errorf("failed to prepare query: %v", err)
400405
return
401406
}
407+
408+
args := make([]any, 200)
409+
for i := 1; i < 200; i+=2 {
410+
args[i] = sval
411+
}
402412
for i := 0; i < 10000; i += 100 {
403-
args := make([]any, 200)
404413
for j := 0; j < 100; j++ {
405414
args[j*2] = i + j
406-
args[j*2+1] = sval
407415
}
408416
_, err := stmt.Exec(args...)
409417
if err != nil {
@@ -413,30 +421,43 @@ func BenchmarkReceiveMassiveRows(b *testing.B) {
413421
}
414422
stmt.Close()
415423

416-
// Use b.Run() to skip expensive setup.
424+
// benchmark function called several times with different b.N.
425+
// it means heavy setup is called multiple times.
426+
// Use b.Run() to run expensive setup only once.
427+
// Go 1.24 introduced b.Loop() for this purpose. But we keep this
428+
// benchmark compatible with Go 1.20.
417429
b.Run("query", func(b *testing.B) {
418430
b.ReportAllocs()
419-
420431
for i := 0; i < b.N; i++ {
421432
rows, err := db.Query(`SELECT id, val FROM foo`)
422433
if err != nil {
423434
b.Errorf("failed to select: %v", err)
424435
return
425436
}
437+
// rows.Scan() escapes arguments. So these variables must be defined
438+
// before loop.
439+
var i int
440+
var s sql.RawBytes
426441
for rows.Next() {
427-
var i int
428-
var s sql.RawBytes
429-
err = rows.Scan(&i, &s)
430-
if err != nil {
442+
if err := rows.Scan(&i, &s); err != nil {
431443
b.Errorf("failed to scan: %v", err)
432-
_ = rows.Close()
444+
rows.Close()
433445
return
434446
}
435447
}
436448
if err = rows.Err(); err != nil {
437449
b.Errorf("failed to read rows: %v", err)
438450
}
439-
_ = rows.Close()
451+
rows.Close()
440452
}
441453
})
442454
}
455+
456+
// BenchmarkReceive10kRows measures performance of receiving large number of rows.
457+
func BenchmarkReceive10kRows(b *testing.B) {
458+
benchmark10kRows(b, false)
459+
}
460+
461+
func BenchmarkReceive10kRowsCompressed(b *testing.B) {
462+
benchmark10kRows(b, true)
463+
}

0 commit comments

Comments
 (0)