From a1c24661cd67ed25285e12ea746edfaf2553be80 Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Mon, 8 Jul 2013 18:11:10 -0500 Subject: [PATCH] Added binary encoding for int2 --- bench_test.go | 61 +++++++++++++++++++++++++++++++++++++++++++++ value_transcoder.go | 18 +++++++++---- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/bench_test.go b/bench_test.go index 19490945..2efd46c9 100644 --- a/bench_test.go +++ b/bench_test.go @@ -8,6 +8,7 @@ import ( var testJoinsDataLoaded bool var narrowTestDataLoaded bool +var int2TextVsBinaryTestDataLoaded bool var int4TextVsBinaryTestDataLoaded bool var int8TextVsBinaryTestDataLoaded bool @@ -227,6 +228,66 @@ func BenchmarkSelectRowsPreparedJoins(b *testing.B) { } } +func createInt2TextVsBinaryTestData(b *testing.B, conn *Connection) { + if int2TextVsBinaryTestDataLoaded { + return + } + + if _, err := conn.Execute(` + drop table if exists t; + + create temporary table t( + a int2 not null, + b int2 not null, + c int2 not null, + d int2 not null, + e int2 not null + ); + + insert into t(a, b, c, d, e) + select + (random() * 32000)::int2, (random() * 32000)::int2, (random() * 32000)::int2, (random() * 32000)::int2, (random() * 32000)::int2 + from generate_series(1, 10); + `); err != nil { + b.Fatalf("Could not set up test data: %v", err) + } + + int2TextVsBinaryTestDataLoaded = true +} + +func BenchmarkInt2Text(b *testing.B) { + conn := getSharedConnection() + createInt2TextVsBinaryTestData(b, conn) + + binaryDecoder := valueTranscoders[oid(21)].DecodeBinary + valueTranscoders[oid(21)].DecodeBinary = nil + defer func() { valueTranscoders[oid(21)].DecodeBinary = binaryDecoder }() + + mustPrepare(b, conn, "selectInt16", "select * from t") + defer func() { conn.Deallocate("selectInt16") }() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if _, err := conn.SelectRows("selectInt16"); err != nil { + b.Fatalf("Failure while benchmarking: %v", err) + } + } +} + +func BenchmarkInt2Binary(b *testing.B) { + conn := getSharedConnection() + createInt2TextVsBinaryTestData(b, conn) + mustPrepare(b, conn, "selectInt16", "select * from t") + defer func() { conn.Deallocate("selectInt16") }() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if _, err := conn.SelectRows("selectInt16"); err != nil { + b.Fatalf("Failure while benchmarking: %v", err) + } + } +} + func createInt4TextVsBinaryTestData(b *testing.B, conn *Connection) { if int4TextVsBinaryTestDataLoaded { return diff --git a/value_transcoder.go b/value_transcoder.go index aa6cfadc..4895a33d 100644 --- a/value_transcoder.go +++ b/value_transcoder.go @@ -41,8 +41,10 @@ func init() { // int2 valueTranscoders[oid(21)] = &valueTranscoder{ - DecodeText: decodeInt2FromText, - EncodeTo: encodeInt2} + DecodeText: decodeInt2FromText, + DecodeBinary: decodeInt2FromBinary, + EncodeTo: encodeInt2, + EncodeFormat: 1} // int4 valueTranscoders[oid(23)] = &valueTranscoder{ @@ -123,11 +125,17 @@ func decodeInt2FromText(mr *MessageReader, size int32) interface{} { return int16(n) } +func decodeInt2FromBinary(mr *MessageReader, size int32) interface{} { + if size != 2 { + panic("Received an invalid size for an int8") + } + return mr.ReadInt16() +} + func encodeInt2(buf *bytes.Buffer, value interface{}) { v := value.(int16) - s := strconv.FormatInt(int64(v), 10) - binary.Write(buf, binary.BigEndian, int32(len(s))) - buf.WriteString(s) + binary.Write(buf, binary.BigEndian, int32(2)) + binary.Write(buf, binary.BigEndian, v) } func decodeInt4FromText(mr *MessageReader, size int32) interface{} {