@@ -372,3 +372,59 @@ func BenchmarkQueryRawBytes(b *testing.B) {
372372 })
373373 }
374374}
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