Improve performance/reduce allocs of bytespipe

Creates a `fixedBuffer` type that is used to encapsulate functionality
for reading/writing from the underlying byte slices.

Uses lazily-loaded set of sync.Pools for storing buffers that are no
longer needed so they can be re-used.

```
benchmark                     old ns/op     new ns/op     delta
BenchmarkBytesPipeWrite-8     138469        48985         -64.62%
BenchmarkBytesPipeRead-8      130922        56601         -56.77%

benchmark                     old allocs     new allocs     delta
BenchmarkBytesPipeWrite-8     18             8              -55.56%
BenchmarkBytesPipeRead-8      0              0              +0.00%

benchmark                     old bytes     new bytes     delta
BenchmarkBytesPipeWrite-8     66903         1649          -97.54%
BenchmarkBytesPipeRead-8      0             1             +Inf%
```

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2016-03-31 09:50:50 -07:00
parent e2664472b6
commit 729c6a44bc
4 changed files with 208 additions and 57 deletions

View file

@ -9,7 +9,7 @@ import (
)
func TestBytesPipeRead(t *testing.T) {
buf := NewBytesPipe(nil)
buf := NewBytesPipe()
buf.Write([]byte("12"))
buf.Write([]byte("34"))
buf.Write([]byte("56"))
@ -49,14 +49,14 @@ func TestBytesPipeRead(t *testing.T) {
}
func TestBytesPipeWrite(t *testing.T) {
buf := NewBytesPipe(nil)
buf := NewBytesPipe()
buf.Write([]byte("12"))
buf.Write([]byte("34"))
buf.Write([]byte("56"))
buf.Write([]byte("78"))
buf.Write([]byte("90"))
if string(buf.buf[0]) != "1234567890" {
t.Fatalf("Buffer %s, must be %s", buf.buf, "1234567890")
if buf.buf[0].String() != "1234567890" {
t.Fatalf("Buffer %q, must be %q", buf.buf[0].String(), "1234567890")
}
}
@ -86,7 +86,7 @@ func TestBytesPipeWriteRandomChunks(t *testing.T) {
expected := hex.EncodeToString(hash.Sum(nil))
// write/read through buffer
buf := NewBytesPipe(nil)
buf := NewBytesPipe()
hash.Reset()
done := make(chan struct{})
@ -124,9 +124,10 @@ func TestBytesPipeWriteRandomChunks(t *testing.T) {
}
func BenchmarkBytesPipeWrite(b *testing.B) {
testData := []byte("pretty short line, because why not?")
for i := 0; i < b.N; i++ {
readBuf := make([]byte, 1024)
buf := NewBytesPipe(nil)
buf := NewBytesPipe()
go func() {
var err error
for err == nil {
@ -134,7 +135,7 @@ func BenchmarkBytesPipeWrite(b *testing.B) {
}
}()
for j := 0; j < 1000; j++ {
buf.Write([]byte("pretty short line, because why not?"))
buf.Write(testData)
}
buf.Close()
}
@ -144,7 +145,7 @@ func BenchmarkBytesPipeRead(b *testing.B) {
rd := make([]byte, 512)
for i := 0; i < b.N; i++ {
b.StopTimer()
buf := NewBytesPipe(nil)
buf := NewBytesPipe()
for j := 0; j < 500; j++ {
buf.Write(make([]byte, 1024))
}