@@ -46,10 +46,10 @@ func (tb *TB) checkStmt(stmt *sql.Stmt, err error) *sql.Stmt {
46
46
return stmt
47
47
}
48
48
49
- func initDB (b * testing.B , useCompression bool , queries ... string ) * sql.DB {
49
+ func initDB (b * testing.B , compress bool , queries ... string ) * sql.DB {
50
50
tb := (* TB )(b )
51
51
comprStr := ""
52
- if useCompression {
52
+ if compress {
53
53
comprStr = "&compress=1"
54
54
}
55
55
db := tb .checkDB (sql .Open (driverNameTest , dsn + comprStr ))
@@ -64,16 +64,15 @@ func initDB(b *testing.B, useCompression bool, queries ...string) *sql.DB {
64
64
const concurrencyLevel = 10
65
65
66
66
func BenchmarkQuery (b * testing.B ) {
67
- benchmarkQueryHelper (b , false )
67
+ benchmarkQuery (b , false )
68
68
}
69
69
70
- func BenchmarkQueryCompression (b * testing.B ) {
71
- benchmarkQueryHelper (b , true )
70
+ func BenchmarkQueryCompressed (b * testing.B ) {
71
+ benchmarkQuery (b , true )
72
72
}
73
73
74
- func benchmarkQueryHelper (b * testing.B , compr bool ) {
74
+ func benchmarkQuery (b * testing.B , compr bool ) {
75
75
tb := (* TB )(b )
76
- b .StopTimer ()
77
76
b .ReportAllocs ()
78
77
db := initDB (b , compr ,
79
78
"DROP TABLE IF EXISTS foo" ,
@@ -115,8 +114,6 @@ func benchmarkQueryHelper(b *testing.B, compr bool) {
115
114
116
115
func BenchmarkExec (b * testing.B ) {
117
116
tb := (* TB )(b )
118
- b .StopTimer ()
119
- b .ReportAllocs ()
120
117
db := tb .checkDB (sql .Open (driverNameTest , dsn ))
121
118
db .SetMaxIdleConns (concurrencyLevel )
122
119
defer db .Close ()
@@ -128,9 +125,17 @@ func BenchmarkExec(b *testing.B) {
128
125
var wg sync.WaitGroup
129
126
wg .Add (concurrencyLevel )
130
127
defer wg .Wait ()
131
- b .StartTimer ()
132
128
129
+ << << << < HEAD
133
130
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 ))
134
139
go func () {
135
140
for {
136
141
if atomic .AddInt64 (& remain , - 1 ) < 0 {
@@ -158,14 +163,15 @@ func initRoundtripBenchmarks() ([]byte, int, int) {
158
163
}
159
164
160
165
func BenchmarkRoundtripTxt (b * testing.B ) {
161
- b .StopTimer ()
162
166
sample , min , max := initRoundtripBenchmarks ()
163
167
sampleString := string (sample )
164
- b .ReportAllocs ()
165
168
tb := (* TB )(b )
166
169
db := tb .checkDB (sql .Open (driverNameTest , dsn ))
167
170
defer db .Close ()
168
- b .StartTimer ()
171
+
172
+ b .ReportAllocs ()
173
+ b .ResetTimer ()
174
+
169
175
var result string
170
176
for i := 0 ; i < b .N ; i ++ {
171
177
length := min + i
@@ -192,15 +198,15 @@ func BenchmarkRoundtripTxt(b *testing.B) {
192
198
}
193
199
194
200
func BenchmarkRoundtripBin (b * testing.B ) {
195
- b .StopTimer ()
196
201
sample , min , max := initRoundtripBenchmarks ()
197
- b .ReportAllocs ()
198
202
tb := (* TB )(b )
199
203
db := tb .checkDB (sql .Open (driverNameTest , dsn ))
200
204
defer db .Close ()
201
205
stmt := tb .checkStmt (db .Prepare ("SELECT ?" ))
202
206
defer stmt .Close ()
203
- b .StartTimer ()
207
+
208
+ b .ReportAllocs ()
209
+ b .ResetTimer ()
204
210
var result sql.RawBytes
205
211
for i := 0 ; i < b .N ; i ++ {
206
212
length := min + i
@@ -385,10 +391,9 @@ func BenchmarkQueryRawBytes(b *testing.B) {
385
391
}
386
392
}
387
393
388
- // BenchmarkReceiveMassiveRows measures performance of receiving large number of rows.
389
- func BenchmarkReceiveMassiveRows (b * testing.B ) {
394
+ func benchmark10kRows (b * testing.B , compress bool ) {
390
395
// Setup -- prepare 10000 rows.
391
- db := initDB (b , false ,
396
+ db := initDB (b , compress ,
392
397
"DROP TABLE IF EXISTS foo" ,
393
398
"CREATE TABLE foo (id INT PRIMARY KEY, val TEXT)" )
394
399
defer db .Close ()
@@ -399,11 +404,14 @@ func BenchmarkReceiveMassiveRows(b *testing.B) {
399
404
b .Errorf ("failed to prepare query: %v" , err )
400
405
return
401
406
}
407
+
408
+ args := make ([]any , 200 )
409
+ for i := 1 ; i < 200 ; i += 2 {
410
+ args [i ] = sval
411
+ }
402
412
for i := 0 ; i < 10000 ; i += 100 {
403
- args := make ([]any , 200 )
404
413
for j := 0 ; j < 100 ; j ++ {
405
414
args [j * 2 ] = i + j
406
- args [j * 2 + 1 ] = sval
407
415
}
408
416
_ , err := stmt .Exec (args ... )
409
417
if err != nil {
@@ -413,30 +421,43 @@ func BenchmarkReceiveMassiveRows(b *testing.B) {
413
421
}
414
422
stmt .Close ()
415
423
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.
417
429
b .Run ("query" , func (b * testing.B ) {
418
430
b .ReportAllocs ()
419
-
420
431
for i := 0 ; i < b .N ; i ++ {
421
432
rows , err := db .Query (`SELECT id, val FROM foo` )
422
433
if err != nil {
423
434
b .Errorf ("failed to select: %v" , err )
424
435
return
425
436
}
437
+ // rows.Scan() escapes arguments. So these variables must be defined
438
+ // before loop.
439
+ var i int
440
+ var s sql.RawBytes
426
441
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 {
431
443
b .Errorf ("failed to scan: %v" , err )
432
- _ = rows .Close ()
444
+ rows .Close ()
433
445
return
434
446
}
435
447
}
436
448
if err = rows .Err (); err != nil {
437
449
b .Errorf ("failed to read rows: %v" , err )
438
450
}
439
- _ = rows .Close ()
451
+ rows .Close ()
440
452
}
441
453
})
442
454
}
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