1package pgtype_test 2 3import ( 4 "testing" 5 6 "github.com/jackc/pgio" 7 "github.com/jackc/pgtype" 8 "github.com/stretchr/testify/require" 9) 10 11type MyCompositeRaw struct { 12 A int32 13 B *string 14} 15 16func (src MyCompositeRaw) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) ([]byte, error) { 17 buf = pgio.AppendUint32(buf, 2) 18 19 buf = pgio.AppendUint32(buf, pgtype.Int4OID) 20 buf = pgio.AppendInt32(buf, 4) 21 buf = pgio.AppendInt32(buf, src.A) 22 23 buf = pgio.AppendUint32(buf, pgtype.TextOID) 24 if src.B != nil { 25 buf = pgio.AppendInt32(buf, int32(len(*src.B))) 26 buf = append(buf, (*src.B)...) 27 } else { 28 buf = pgio.AppendInt32(buf, -1) 29 } 30 31 return buf, nil 32} 33 34func (dst *MyCompositeRaw) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error { 35 a := pgtype.Int4{} 36 b := pgtype.Text{} 37 38 scanner := pgtype.NewCompositeBinaryScanner(ci, src) 39 scanner.ScanDecoder(&a) 40 scanner.ScanDecoder(&b) 41 42 if scanner.Err() != nil { 43 return scanner.Err() 44 } 45 46 dst.A = a.Int 47 if b.Status == pgtype.Present { 48 dst.B = &b.String 49 } else { 50 dst.B = nil 51 } 52 53 return nil 54} 55 56var x []byte 57 58func BenchmarkBinaryEncodingManual(b *testing.B) { 59 buf := make([]byte, 0, 128) 60 ci := pgtype.NewConnInfo() 61 v := MyCompositeRaw{4, ptrS("ABCDEFG")} 62 63 b.ResetTimer() 64 for n := 0; n < b.N; n++ { 65 buf, _ = v.EncodeBinary(ci, buf[:0]) 66 } 67 x = buf 68} 69 70func BenchmarkBinaryEncodingHelper(b *testing.B) { 71 buf := make([]byte, 0, 128) 72 ci := pgtype.NewConnInfo() 73 v := MyType{4, ptrS("ABCDEFG")} 74 75 b.ResetTimer() 76 for n := 0; n < b.N; n++ { 77 buf, _ = v.EncodeBinary(ci, buf[:0]) 78 } 79 x = buf 80} 81 82func BenchmarkBinaryEncodingComposite(b *testing.B) { 83 buf := make([]byte, 0, 128) 84 ci := pgtype.NewConnInfo() 85 f1 := 2 86 f2 := ptrS("bar") 87 c, err := pgtype.NewCompositeType("test", []pgtype.CompositeTypeField{ 88 {"a", pgtype.Int4OID}, 89 {"b", pgtype.TextOID}, 90 }, ci) 91 require.NoError(b, err) 92 93 b.ResetTimer() 94 for n := 0; n < b.N; n++ { 95 c.Set([]interface{}{f1, f2}) 96 buf, _ = c.EncodeBinary(ci, buf[:0]) 97 } 98 x = buf 99} 100 101func BenchmarkBinaryEncodingJSON(b *testing.B) { 102 buf := make([]byte, 0, 128) 103 ci := pgtype.NewConnInfo() 104 v := MyCompositeRaw{4, ptrS("ABCDEFG")} 105 j := pgtype.JSON{} 106 107 b.ResetTimer() 108 for n := 0; n < b.N; n++ { 109 j.Set(v) 110 buf, _ = j.EncodeBinary(ci, buf[:0]) 111 } 112 x = buf 113} 114 115var dstRaw MyCompositeRaw 116 117func BenchmarkBinaryDecodingManual(b *testing.B) { 118 ci := pgtype.NewConnInfo() 119 buf, _ := MyType{4, ptrS("ABCDEFG")}.EncodeBinary(ci, nil) 120 dst := MyCompositeRaw{} 121 122 b.ResetTimer() 123 for n := 0; n < b.N; n++ { 124 err := dst.DecodeBinary(ci, buf) 125 E(err) 126 } 127 dstRaw = dst 128} 129 130var dstMyType MyType 131 132func BenchmarkBinaryDecodingHelpers(b *testing.B) { 133 ci := pgtype.NewConnInfo() 134 buf, _ := MyType{4, ptrS("ABCDEFG")}.EncodeBinary(ci, nil) 135 dst := MyType{} 136 137 b.ResetTimer() 138 for n := 0; n < b.N; n++ { 139 err := dst.DecodeBinary(ci, buf) 140 E(err) 141 } 142 dstMyType = dst 143} 144 145var gf1 int 146var gf2 *string 147 148func BenchmarkBinaryDecodingCompositeScan(b *testing.B) { 149 ci := pgtype.NewConnInfo() 150 buf, _ := MyType{4, ptrS("ABCDEFG")}.EncodeBinary(ci, nil) 151 var f1 int 152 var f2 *string 153 154 c, err := pgtype.NewCompositeType("test", []pgtype.CompositeTypeField{ 155 {"a", pgtype.Int4OID}, 156 {"b", pgtype.TextOID}, 157 }, ci) 158 require.NoError(b, err) 159 160 b.ResetTimer() 161 for n := 0; n < b.N; n++ { 162 err := c.DecodeBinary(ci, buf) 163 if err != nil { 164 b.Fatal(err) 165 } 166 err = c.AssignTo([]interface{}{&f1, &f2}) 167 if err != nil { 168 b.Fatal(err) 169 } 170 } 171 gf1 = f1 172 gf2 = f2 173} 174 175func BenchmarkBinaryDecodingJSON(b *testing.B) { 176 ci := pgtype.NewConnInfo() 177 j := pgtype.JSON{} 178 j.Set(MyCompositeRaw{4, ptrS("ABCDEFG")}) 179 buf, _ := j.EncodeBinary(ci, nil) 180 181 j = pgtype.JSON{} 182 dst := MyCompositeRaw{} 183 184 b.ResetTimer() 185 for n := 0; n < b.N; n++ { 186 err := j.DecodeBinary(ci, buf) 187 E(err) 188 err = j.AssignTo(&dst) 189 E(err) 190 } 191 dstRaw = dst 192} 193