Skip to content

Commit

Permalink
added benchmark for bytestream.Consume
Browse files Browse the repository at this point in the history
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
  • Loading branch information
fredbi committed Dec 11, 2023
1 parent 86008b7 commit d9f89fe
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 5 deletions.
2 changes: 1 addition & 1 deletion bytestream.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func ByteStreamConsumer(opts ...byteStreamOpt) Consumer {
}

// buffers input before writing to data
buf := new(bytes.Buffer)
var buf bytes.Buffer
_, err := buf.ReadFrom(reader)
if err != nil {
return err
Expand Down
108 changes: 104 additions & 4 deletions bytestream_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package runtime

import (
"bytes"
"crypto/rand"
"errors"
"fmt"
"io"
"sync/atomic"
"testing"

Expand All @@ -27,7 +29,7 @@ func TestByteStreamConsumer(t *testing.T) {
assert.Equal(t, expected, dest)
})

t.Run("can consume as an UnmarshalBinary", func(t *testing.T) {
t.Run("can consume as a binary unmarshaler", func(t *testing.T) {
var dest binaryUnmarshalDummy
require.NoError(t, consumer.Consume(bytes.NewBufferString(expected), &dest))
assert.Equal(t, expected, dest.str)
Expand Down Expand Up @@ -103,16 +105,114 @@ func TestByteStreamConsumer(t *testing.T) {
})
}

func BenchmarkByteStreamConsumer(b *testing.B) {
const bufferSize = 1000
expected := make([]byte, bufferSize)
_, err := rand.Read(expected)
require.NoError(b, err)
consumer := ByteStreamConsumer()
input := bytes.NewReader(expected)

b.Run("with writer", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
var dest bytes.Buffer
for i := 0; i < b.N; i++ {
err = consumer.Consume(input, &dest)
if err != nil {
b.Fatal(err)
}
_, _ = input.Seek(0, io.SeekStart)
dest.Reset()
}
})
b.Run("with BinaryUnmarshal", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
var dest binaryUnmarshalDummyZeroAlloc
for i := 0; i < b.N; i++ {
err = consumer.Consume(input, &dest)
if err != nil {
b.Fatal(err)
}
_, _ = input.Seek(0, io.SeekStart)
}
})
b.Run("with string", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
var dest string
for i := 0; i < b.N; i++ {
err = consumer.Consume(input, &dest)
if err != nil {
b.Fatal(err)
}
_, _ = input.Seek(0, io.SeekStart)
}
})
b.Run("with []byte", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
var dest []byte
for i := 0; i < b.N; i++ {
err = consumer.Consume(input, &dest)
if err != nil {
b.Fatal(err)
}
_, _ = input.Seek(0, io.SeekStart)
}
})
b.Run("with aliased string", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
type aliasedString string
var dest aliasedString
for i := 0; i < b.N; i++ {
err = consumer.Consume(input, &dest)
if err != nil {
b.Fatal(err)
}
_, _ = input.Seek(0, io.SeekStart)
}
})
b.Run("with aliased []byte", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
type binarySlice []byte
var dest binarySlice
for i := 0; i < b.N; i++ {
err = consumer.Consume(input, &dest)
if err != nil {
b.Fatal(err)
}
_, _ = input.Seek(0, io.SeekStart)
}
})
}

type binaryUnmarshalDummy struct {
str string
}

func (b *binaryUnmarshalDummy) UnmarshalBinary(bytes []byte) error {
if len(bytes) == 0 {
type binaryUnmarshalDummyZeroAlloc struct {
b []byte
}

func (b *binaryUnmarshalDummy) UnmarshalBinary(data []byte) error {
if len(data) == 0 {
return errors.New("no text given")
}

b.str = string(data)
return nil
}

func (b *binaryUnmarshalDummyZeroAlloc) UnmarshalBinary(data []byte) error {
if len(data) == 0 {
return errors.New("no text given")
}

b.str = string(bytes)
b.b = data
return nil
}

Expand Down

0 comments on commit d9f89fe

Please sign in to comment.