Skip to content

Commit 2ed589b

Browse files
authored
backport benchmark_test (#1706)
Backport benchmark improvements.
1 parent ac04e5f commit 2ed589b

File tree

2 files changed

+49
-30
lines changed

2 files changed

+49
-30
lines changed

‎.github/workflows/test.yml‎

Lines changed: 4 additions & 0 deletions
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‎

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ func (tb *TB) checkStmt(stmt *sql.Stmt, err error) *sql.Stmt{
4646
returnstmt
4747
}
4848

49-
funcinitDB(b*testing.B, useCompressionbool, queries...string) *sql.DB{
49+
funcinitDB(b*testing.B, compressbool, queries...string) *sql.DB{
5050
tb:= (*TB)(b)
5151
comprStr:=""
52-
ifuseCompression{
52+
ifcompress{
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
constconcurrencyLevel=10
6565

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

70-
funcBenchmarkQueryCompression(b*testing.B){
71-
benchmarkQueryHelper(b, true)
70+
funcBenchmarkQueryCompressed(b*testing.B){
71+
benchmarkQuery(b, true)
7272
}
7373

74-
funcbenchmarkQueryHelper(b*testing.B, comprbool){
74+
funcbenchmarkQuery(b*testing.B, comprbool){
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
funcBenchmarkExec(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
deferdb.Close()
@@ -128,9 +125,11 @@ func BenchmarkExec(b *testing.B){
128125
varwg sync.WaitGroup
129126
wg.Add(concurrencyLevel)
130127
deferwg.Wait()
131-
b.StartTimer()
132128

133-
fori:=0; i<concurrencyLevel; i++{
129+
b.ReportAllocs()
130+
b.ResetTimer()
131+
132+
fori:=0; i<concurrencyLevel; i++{
134133
gofunc(){
135134
for{
136135
ifatomic.AddInt64(&remain, -1) <0{
@@ -158,14 +157,15 @@ func initRoundtripBenchmarks() ([]byte, int, int){
158157
}
159158

160159
funcBenchmarkRoundtripTxt(b*testing.B){
161-
b.StopTimer()
162160
sample, min, max:=initRoundtripBenchmarks()
163161
sampleString:=string(sample)
164-
b.ReportAllocs()
165162
tb:= (*TB)(b)
166163
db:=tb.checkDB(sql.Open(driverNameTest, dsn))
167164
deferdb.Close()
168-
b.StartTimer()
165+
166+
b.ReportAllocs()
167+
b.ResetTimer()
168+
169169
varresultstring
170170
fori:=0; i<b.N; i++{
171171
length:=min+i
@@ -192,15 +192,15 @@ func BenchmarkRoundtripTxt(b *testing.B){
192192
}
193193

194194
funcBenchmarkRoundtripBin(b*testing.B){
195-
b.StopTimer()
196195
sample, min, max:=initRoundtripBenchmarks()
197-
b.ReportAllocs()
198196
tb:= (*TB)(b)
199197
db:=tb.checkDB(sql.Open(driverNameTest, dsn))
200198
deferdb.Close()
201199
stmt:=tb.checkStmt(db.Prepare("SELECT ?"))
202200
deferstmt.Close()
203-
b.StartTimer()
201+
202+
b.ReportAllocs()
203+
b.ResetTimer()
204204
varresult sql.RawBytes
205205
fori:=0; i<b.N; i++{
206206
length:=min+i
@@ -385,10 +385,9 @@ func BenchmarkQueryRawBytes(b *testing.B){
385385
}
386386
}
387387

388-
// BenchmarkReceiveMassiveRows measures performance of receiving large number of rows.
389-
funcBenchmarkReceiveMassiveRows(b*testing.B){
388+
funcbenchmark10kRows(b*testing.B, compressbool){
390389
// Setup -- prepare 10000 rows.
391-
db:=initDB(b, false,
390+
db:=initDB(b, compress,
392391
"DROP TABLE IF EXISTS foo",
393392
"CREATE TABLE foo (id INT PRIMARY KEY, val TEXT)")
394393
deferdb.Close()
@@ -399,11 +398,14 @@ func BenchmarkReceiveMassiveRows(b *testing.B){
399398
b.Errorf("failed to prepare query: %v", err)
400399
return
401400
}
401+
402+
args:=make([]any, 200)
403+
fori:=1; i<200; i+=2{
404+
args[i] =sval
405+
}
402406
fori:=0; i<10000; i+=100{
403-
args:=make([]any, 200)
404407
forj:=0; j<100; j++{
405408
args[j*2] =i+j
406-
args[j*2+1] =sval
407409
}
408410
_, err:=stmt.Exec(args...)
409411
iferr!=nil{
@@ -413,30 +415,43 @@ func BenchmarkReceiveMassiveRows(b *testing.B){
413415
}
414416
stmt.Close()
415417

416-
// Use b.Run() to skip expensive setup.
418+
// benchmark function called several times with different b.N.
419+
// it means heavy setup is called multiple times.
420+
// Use b.Run() to run expensive setup only once.
421+
// Go 1.24 introduced b.Loop() for this purpose. But we keep this
422+
// benchmark compatible with Go 1.20.
417423
b.Run("query", func(b*testing.B){
418424
b.ReportAllocs()
419-
420425
fori:=0; i<b.N; i++{
421426
rows, err:=db.Query(`SELECT id, val FROM foo`)
422427
iferr!=nil{
423428
b.Errorf("failed to select: %v", err)
424429
return
425430
}
431+
// rows.Scan() escapes arguments. So these variables must be defined
432+
// before loop.
433+
variint
434+
vars sql.RawBytes
426435
forrows.Next(){
427-
variint
428-
vars sql.RawBytes
429-
err=rows.Scan(&i, &s)
430-
iferr!=nil{
436+
iferr:=rows.Scan(&i, &s); err!=nil{
431437
b.Errorf("failed to scan: %v", err)
432-
_=rows.Close()
438+
rows.Close()
433439
return
434440
}
435441
}
436442
iferr=rows.Err(); err!=nil{
437443
b.Errorf("failed to read rows: %v", err)
438444
}
439-
_=rows.Close()
445+
rows.Close()
440446
}
441447
})
442448
}
449+
450+
// BenchmarkReceive10kRows measures performance of receiving large number of rows.
451+
funcBenchmarkReceive10kRows(b*testing.B){
452+
benchmark10kRows(b, false)
453+
}
454+
455+
funcBenchmarkReceive10kRowsCompressed(b*testing.B){
456+
benchmark10kRows(b, true)
457+
}

0 commit comments

Comments
(0)