Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encoding speedups for strings and bools #77

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions binary_serialization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ func TestBooleanSerialization(t *testing.T) {
}
}

func BenchmarkBooleanSerialization(b *testing.B) {
buf := &bytes.Buffer{}
enc := NewBinaryEncoder(buf)
b.ResetTimer()
for i := 0; i < b.N; i++ {
enc.WriteBoolean(true)
buf.Reset()
}
}

func TestIntSerialization(t *testing.T) {
testPrimitiveSerialization(t, func(i int) interface{} {
r := rand.Int31() / (int32(i) * int32(i))
Expand Down Expand Up @@ -120,6 +130,34 @@ func TestStringSerialization(t *testing.T) {
})
}

func BenchmarkStringSerialization_small(b *testing.B) {
benchStringSerialization(b, 10)
}

func BenchmarkStringSerialization_med(b *testing.B) {
benchStringSerialization(b, 70)
}

func BenchmarkStringSerialization_large(b *testing.B) {
benchStringSerialization(b, 2000)
}

func benchStringSerialization(b *testing.B, n int) {
s := "abcdefghijklmnop"
for len(s) < n {
s += s
}
s = s[:n]

buf := &bytes.Buffer{}
enc := NewBinaryEncoder(buf)
b.ResetTimer()
for i := 0; i < b.N; i++ {
enc.WriteString(s)
buf.Reset()
}
}

func testPrimitiveSerialization(t *testing.T, random func(int) interface{}, serialize func(interface{}) (interface{}, error)) {
for i := 1; i <= testTimes; i++ {
r := random(i)
Expand Down
11 changes: 8 additions & 3 deletions encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,16 @@ func (be *BinaryEncoder) WriteNull(_ interface{}) {
//do nothing
}

// The encodings of true and false, for reuse
var encBoolTrue = []byte{0x01}
var encBoolFalse = []byte{0x00}

// WriteBoolean writes a boolean value.
func (be *BinaryEncoder) WriteBoolean(x bool) {
if x {
_, _ = be.buffer.Write([]byte{0x01})
_, _ = be.buffer.Write(encBoolTrue)
} else {
_, _ = be.buffer.Write([]byte{0x00})
_, _ = be.buffer.Write(encBoolFalse)
}
}

Expand Down Expand Up @@ -115,7 +119,8 @@ func (be *BinaryEncoder) WriteBytes(x []byte) {
// WriteString writes a string value.
func (be *BinaryEncoder) WriteString(x string) {
be.WriteLong(int64(len(x)))
_, _ = be.buffer.Write([]byte(x))
// call writers that happen to provide WriteString to avoid extra byte allocations for a copy of a string when possible.
_, _ = io.WriteString(be.buffer, x)
}

// WriteArrayStart should be called when starting to serialize an array providing it with a number of items in
Expand Down