mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
bytes: don't grow Buffer if capacity is available
Also added a new benchmark from the same test: benchmark old ns/op new ns/op delta BenchmarkBufferNotEmptyWriteRead 2643698 709189 -73.17% Fixes #5154 R=golang-dev, r, gri CC=golang-dev https://golang.org/cl/8164043
This commit is contained in:
parent
fb3ed166e3
commit
994f59666f
3 changed files with 41 additions and 0 deletions
|
|
@ -87,6 +87,11 @@ func (b *Buffer) grow(n int) int {
|
||||||
var buf []byte
|
var buf []byte
|
||||||
if b.buf == nil && n <= len(b.bootstrap) {
|
if b.buf == nil && n <= len(b.bootstrap) {
|
||||||
buf = b.bootstrap[0:]
|
buf = b.bootstrap[0:]
|
||||||
|
} else if m+n <= cap(b.buf) {
|
||||||
|
// We can slide things down instead of
|
||||||
|
// allocating a new slice.
|
||||||
|
copy(b.buf[:], b.buf[b.off:])
|
||||||
|
buf = b.buf[:m]
|
||||||
} else {
|
} else {
|
||||||
// not enough space anywhere
|
// not enough space anywhere
|
||||||
buf = makeSlice(2*cap(b.buf) + n)
|
buf = makeSlice(2*cap(b.buf) + n)
|
||||||
|
|
|
||||||
|
|
@ -475,3 +475,35 @@ func TestUnreadByte(t *testing.T) {
|
||||||
t.Errorf("ReadByte = %q; want %q", c, 'm')
|
t.Errorf("ReadByte = %q; want %q", c, 'm')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that we occasionally compact. Issue 5154.
|
||||||
|
func TestBufferGrowth(t *testing.T) {
|
||||||
|
var b Buffer
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
b.Write(buf[0:1])
|
||||||
|
var cap0 int
|
||||||
|
for i := 0; i < 5<<10; i++ {
|
||||||
|
b.Write(buf)
|
||||||
|
b.Read(buf)
|
||||||
|
if i == 0 {
|
||||||
|
cap0 = b.Cap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cap1 := b.Cap()
|
||||||
|
if cap1 > cap0 {
|
||||||
|
t.Errorf("buffer cap = %d; too big", cap1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// From Issue 5154.
|
||||||
|
func BenchmarkBufferNotEmptyWriteRead(b *testing.B) {
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
var b Buffer
|
||||||
|
b.Write(buf[0:1])
|
||||||
|
for i := 0; i < 5<<10; i++ {
|
||||||
|
b.Write(buf)
|
||||||
|
b.Read(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,7 @@ package bytes
|
||||||
// Export func for testing
|
// Export func for testing
|
||||||
var IndexBytePortable = indexBytePortable
|
var IndexBytePortable = indexBytePortable
|
||||||
var EqualPortable = equalPortable
|
var EqualPortable = equalPortable
|
||||||
|
|
||||||
|
func (b *Buffer) Cap() int {
|
||||||
|
return cap(b.buf)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue