diff --git a/composite_bench_test.go b/composite_bench_test.go index 154b2e26..30e48ae7 100644 --- a/composite_bench_test.go +++ b/composite_bench_test.go @@ -5,6 +5,7 @@ import ( "github.com/jackc/pgtype" "github.com/jackc/pgtype/binary" + errors "golang.org/x/xerrors" ) type MyCompositeRaw struct { @@ -30,6 +31,45 @@ func (src MyCompositeRaw) EncodeBinary(ci *pgtype.ConnInfo, buf []byte) (newBuf return } +func (dst *MyCompositeRaw) DecodeBinary(ci *pgtype.ConnInfo, src []byte) error { + a := pgtype.Int4{} + b := pgtype.Text{} + + fieldIter, fieldCount, err := binary.NewRecordFieldIterator(src) + if err != nil { + return err + } + + if 2 != fieldCount { + return errors.Errorf("can't scan row value, number of fields don't match: found=%d expected=2", fieldCount) + } + + _, fieldBytes, eof, err := fieldIter.Next() + if eof || err != nil { + return errors.New("Bad record") + } + if err = a.DecodeBinary(ci, fieldBytes); err != nil { + return err + } + + _, fieldBytes, eof, err = fieldIter.Next() + if eof || err != nil { + return errors.New("Bad record") + } + if err = b.DecodeBinary(ci, fieldBytes); err != nil { + return err + } + + dst.a = a.Int + if b.Status == pgtype.Present { + dst.b = &b.String + } else { + dst.b = nil + } + + return nil +} + var x []byte func BenchmarkBinaryEncodingManual(b *testing.B) { @@ -70,3 +110,52 @@ func BenchmarkBinaryEncodingRow(b *testing.B) { } x = buf } + +var dstRaw MyCompositeRaw + +func BenchmarkBinaryDecodingManual(b *testing.B) { + ci := pgtype.NewConnInfo() + buf, _ := MyType{4, ptrS("ABCDEFG")}.EncodeBinary(ci, nil) + dst := MyCompositeRaw{} + + b.ResetTimer() + for n := 0; n < b.N; n++ { + err := dst.DecodeBinary(ci, buf) + E(err) + } + dstRaw = dst +} + +var dstMyType MyType + +func BenchmarkBinaryDecodingHelpers(b *testing.B) { + ci := pgtype.NewConnInfo() + buf, _ := MyType{4, ptrS("ABCDEFG")}.EncodeBinary(ci, nil) + dst := MyType{} + + b.ResetTimer() + for n := 0; n < b.N; n++ { + err := dst.DecodeBinary(ci, buf) + E(err) + } + dstMyType = dst +} + +var gf1 int +var gf2 *string + +func BenchmarkBinaryDecodingRow(b *testing.B) { + ci := pgtype.NewConnInfo() + buf, _ := MyType{4, ptrS("ABCDEFG")}.EncodeBinary(ci, nil) + var isNull bool + var f1 int + var f2 *string + + b.ResetTimer() + for n := 0; n < b.N; n++ { + err := pgtype.Row(&isNull, &f1, &f2).DecodeBinary(ci, buf) + E(err) + } + gf1 = f1 + gf2 = f2 +}