diff options
author | Russ Cox <rsc@golang.org> | 2010-04-14 01:52:56 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2010-04-14 01:52:56 -0700 |
commit | 39656bb7a4553416504d2cbbf5d7ef9e0e0904b9 (patch) | |
tree | 36ce86f48398f2d6e68c256ce8b345a9451a236a | |
parent | c837bc86e431c78e3acd59ae46350e49d1abb464 (diff) | |
download | golang-39656bb7a4553416504d2cbbf5d7ef9e0e0904b9.tar.gz |
bytes: shuffle implementation, making WriteByte 50% faster
R=r
CC=golang-dev
http://codereview.appspot.com/920041
-rw-r--r-- | src/pkg/bytes/buffer.go | 64 |
1 files changed, 27 insertions, 37 deletions
diff --git a/src/pkg/bytes/buffer.go b/src/pkg/bytes/buffer.go index acd4523ad..faccca3be 100644 --- a/src/pkg/bytes/buffer.go +++ b/src/pkg/bytes/buffer.go @@ -63,54 +63,44 @@ func (b *Buffer) Truncate(n int) { // b.Reset() is the same as b.Truncate(0). func (b *Buffer) Reset() { b.Truncate(0) } -// Resize buffer to guarantee enough space for n more bytes. -// After this call, the state of b.buf is inconsistent. -// It must be fixed up as is done in Write and WriteString. -func (b *Buffer) resize(n int) { - var buf []byte - if b.buf == nil && n <= len(b.bootstrap) { - buf = &b.bootstrap - } else { - // not enough space anywhere - buf = make([]byte, 2*cap(b.buf)+n) - copy(buf, b.buf[b.off:]) - } - b.buf = buf - b.off = 0 -} - -// Write appends the contents of p to the buffer. The return -// value n is the length of p; err is always nil. -func (b *Buffer) Write(p []byte) (n int, err os.Error) { +// Grow buffer to guarantee space for n more bytes. +// Return index where bytes should be written. +func (b *Buffer) grow(n int) int { m := b.Len() // If buffer is empty, reset to recover space. if m == 0 && b.off != 0 { b.Truncate(0) } - n = len(p) if len(b.buf)+n > cap(b.buf) { - b.resize(n) + var buf []byte + if b.buf == nil && n <= len(b.bootstrap) { + buf = &b.bootstrap + } else { + // not enough space anywhere + buf = make([]byte, 2*cap(b.buf)+n) + copy(buf, b.buf[b.off:]) + } + b.buf = buf + b.off = 0 } b.buf = b.buf[0 : b.off+m+n] - copy(b.buf[b.off+m:], p) - return n, nil + return b.off + m +} + +// Write appends the contents of p to the buffer. The return +// value n is the length of p; err is always nil. +func (b *Buffer) Write(p []byte) (n int, err os.Error) { + m := b.grow(len(p)) + copy(b.buf[m:], p) + return len(p), nil } // WriteString appends the contents of s to the buffer. The return // value n is the length of s; err is always nil. func (b *Buffer) WriteString(s string) (n int, err os.Error) { - m := b.Len() - // If buffer is empty, reset to recover space. - if m == 0 && b.off != 0 { - b.Truncate(0) - } - n = len(s) - if len(b.buf)+n > cap(b.buf) { - b.resize(n) - } - b.buf = b.buf[0 : b.off+m+n] - copyString(b.buf, b.off+m, s) - return n, nil + m := b.grow(len(s)) + copyString(b.buf, m, s) + return len(s), nil } // MinRead is the minimum slice size passed to a Read call by @@ -177,8 +167,8 @@ func (b *Buffer) WriteTo(w io.Writer) (n int64, err os.Error) { // The returned error is always nil, but is included // to match bufio.Writer's WriteByte. func (b *Buffer) WriteByte(c byte) os.Error { - b.runeBytes[0] = c - b.Write(b.runeBytes[0:1]) + m := b.grow(1) + b.buf[m] = c return nil } |