mirror of
https://github.com/golang/go
synced 2024-11-25 14:07:56 -07:00
bytes: shuffle implementation, making WriteByte 50% faster
R=r CC=golang-dev https://golang.org/cl/920041
This commit is contained in:
parent
ba1e025fa3
commit
1baf35e41f
@ -63,54 +63,44 @@ func (b *Buffer) Truncate(n int) {
|
|||||||
// b.Reset() is the same as b.Truncate(0).
|
// b.Reset() is the same as b.Truncate(0).
|
||||||
func (b *Buffer) Reset() { b.Truncate(0) }
|
func (b *Buffer) Reset() { b.Truncate(0) }
|
||||||
|
|
||||||
// Resize buffer to guarantee enough space for n more bytes.
|
// Grow buffer to guarantee space for n more bytes.
|
||||||
// After this call, the state of b.buf is inconsistent.
|
// Return index where bytes should be written.
|
||||||
// It must be fixed up as is done in Write and WriteString.
|
func (b *Buffer) grow(n int) int {
|
||||||
func (b *Buffer) resize(n int) {
|
m := b.Len()
|
||||||
var buf []byte
|
// If buffer is empty, reset to recover space.
|
||||||
if b.buf == nil && n <= len(b.bootstrap) {
|
if m == 0 && b.off != 0 {
|
||||||
buf = &b.bootstrap
|
b.Truncate(0)
|
||||||
} else {
|
|
||||||
// not enough space anywhere
|
|
||||||
buf = make([]byte, 2*cap(b.buf)+n)
|
|
||||||
copy(buf, b.buf[b.off:])
|
|
||||||
}
|
}
|
||||||
b.buf = buf
|
if len(b.buf)+n > cap(b.buf) {
|
||||||
b.off = 0
|
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]
|
||||||
|
return b.off + m
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write appends the contents of p to the buffer. The return
|
// Write appends the contents of p to the buffer. The return
|
||||||
// value n is the length of p; err is always nil.
|
// value n is the length of p; err is always nil.
|
||||||
func (b *Buffer) Write(p []byte) (n int, err os.Error) {
|
func (b *Buffer) Write(p []byte) (n int, err os.Error) {
|
||||||
m := b.Len()
|
m := b.grow(len(p))
|
||||||
// If buffer is empty, reset to recover space.
|
copy(b.buf[m:], p)
|
||||||
if m == 0 && b.off != 0 {
|
return len(p), nil
|
||||||
b.Truncate(0)
|
|
||||||
}
|
|
||||||
n = len(p)
|
|
||||||
if len(b.buf)+n > cap(b.buf) {
|
|
||||||
b.resize(n)
|
|
||||||
}
|
|
||||||
b.buf = b.buf[0 : b.off+m+n]
|
|
||||||
copy(b.buf[b.off+m:], p)
|
|
||||||
return n, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteString appends the contents of s to the buffer. The return
|
// WriteString appends the contents of s to the buffer. The return
|
||||||
// value n is the length of s; err is always nil.
|
// value n is the length of s; err is always nil.
|
||||||
func (b *Buffer) WriteString(s string) (n int, err os.Error) {
|
func (b *Buffer) WriteString(s string) (n int, err os.Error) {
|
||||||
m := b.Len()
|
m := b.grow(len(s))
|
||||||
// If buffer is empty, reset to recover space.
|
copyString(b.buf, m, s)
|
||||||
if m == 0 && b.off != 0 {
|
return len(s), nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MinRead is the minimum slice size passed to a Read call by
|
// 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
|
// The returned error is always nil, but is included
|
||||||
// to match bufio.Writer's WriteByte.
|
// to match bufio.Writer's WriteByte.
|
||||||
func (b *Buffer) WriteByte(c byte) os.Error {
|
func (b *Buffer) WriteByte(c byte) os.Error {
|
||||||
b.runeBytes[0] = c
|
m := b.grow(1)
|
||||||
b.Write(b.runeBytes[0:1])
|
b.buf[m] = c
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user