github.com/octohelm/storage@v0.0.0-20240516030302-1ac2cc1ea347/internal/sql/scanner/struct_test.go (about) 1 package scanner 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/DATA-DOG/go-sqlmock" 8 "github.com/octohelm/storage/internal/sql/scanner/nullable" 9 ) 10 11 func BenchmarkScanStruct(b *testing.B) { 12 db, mock, _ := sqlmock.New() 13 defer db.Close() 14 15 mockRows := mock.NewRows([]string{"f_i", "f_s"}) 16 17 b.Run("Direct", func(b *testing.B) { 18 target := &T2{} 19 _ = mock.ExpectQuery("SELECT .+ from t").WillReturnRows(mockRows) 20 21 rows, _ := db.Query("SELECT f_i,f_s from t") 22 23 for i := 0; i < b.N; i++ { 24 mockRows.AddRow(i, "a") 25 26 cs, _ := rows.Columns() 27 28 if rows.Next() { 29 dest := make([]interface{}, len(cs)) 30 crs := target.ColumnReceivers() 31 for i := range cs { 32 dest[i] = nullable.NewNullIgnoreScanner(crs[cs[i]]) 33 } 34 _ = rows.Scan(dest...) 35 } 36 } 37 38 b.Log(target) 39 }) 40 41 b.Run("Scan by reflect", func(b *testing.B) { 42 target := &T{} 43 _ = mock.ExpectQuery("SELECT .+ from t").WillReturnRows(mockRows) 44 45 rows, _ := db.Query("SELECT f_i,f_s from t") 46 47 for i := 0; i < b.N; i++ { 48 mockRows.AddRow(i, "b") 49 50 if rows.Next() { 51 _ = scanTo(context.Background(), rows, target) 52 } 53 } 54 55 b.Log(target) 56 }) 57 58 b.Run("Scan by column receivers", func(b *testing.B) { 59 target := &T2{} 60 _ = mock.ExpectQuery("SELECT .+ from t").WillReturnRows(mockRows) 61 62 rows, _ := db.Query("SELECT f_i,f_s from t") 63 64 for i := 0; i < b.N; i++ { 65 mockRows.AddRow(i, "c") 66 67 if rows.Next() { 68 _ = scanTo(context.Background(), rows, target) 69 } 70 } 71 72 b.Log(target) 73 }) 74 }