@@ -372,3 +372,59 @@ func BenchmarkQueryRawBytes(b *testing.B) {
372
372
})
373
373
}
374
374
}
375
+
376
+ // BenchmarkReceiveMassiveRows measures performance of receiving large number of rows.
377
+ func BenchmarkReceiveMassiveRows (b * testing.B ) {
378
+ // Setup -- prepare 10000 rows.
379
+ db := initDB (b ,
380
+ "DROP TABLE IF EXISTS foo" ,
381
+ "CREATE TABLE foo (id INT PRIMARY KEY, val TEXT)" )
382
+ defer db .Close ()
383
+
384
+ sval := strings .Repeat ("x" , 50 )
385
+ stmt , err := db .Prepare (`INSERT INTO foo (id, val) VALUES (?, ?)` + strings .Repeat (",(?,?)" , 99 ))
386
+ if err != nil {
387
+ b .Errorf ("failed to prepare query: %v" , err )
388
+ return
389
+ }
390
+ for i := 0 ; i < 10000 ; i += 100 {
391
+ args := make ([]any , 200 )
392
+ for j := 0 ; j < 100 ; j ++ {
393
+ args [j * 2 ] = i + j
394
+ args [j * 2 + 1 ] = sval
395
+ }
396
+ _ , err := stmt .Exec (args ... )
397
+ if err != nil {
398
+ b .Error (err )
399
+ return
400
+ }
401
+ }
402
+ stmt .Close ()
403
+
404
+ // Use b.Run() to skip expensive setup.
405
+ b .Run ("query" , func (b * testing.B ) {
406
+ b .ReportAllocs ()
407
+
408
+ for i := 0 ; i < b .N ; i ++ {
409
+ rows , err := db .Query (`SELECT id, val FROM foo` )
410
+ if err != nil {
411
+ b .Errorf ("failed to select: %v" , err )
412
+ return
413
+ }
414
+ for rows .Next () {
415
+ var i int
416
+ var s sql.RawBytes
417
+ err = rows .Scan (& i , & s )
418
+ if err != nil {
419
+ b .Errorf ("failed to scan: %v" , err )
420
+ _ = rows .Close ()
421
+ return
422
+ }
423
+ }
424
+ if err = rows .Err (); err != nil {
425
+ b .Errorf ("failed to read rows: %v" , err )
426
+ }
427
+ _ = rows .Close ()
428
+ }
429
+ })
430
+ }
0 commit comments