指定可写缓冲区大小
代码实现
type truncateBuffer struct {
buf []byte
}
func newTruncateBuffer() *truncateBuffer {
return &truncateBuffer{buf: make([]byte, 0, 1024*1024)}
}
func (b *truncateBuffer) Write(p []byte) (n int, err error) {
pLen := len(p)
bLen := len(b.buf)
bCap := cap(b.buf)
if bCap == bLen {
return pLen, nil
} else if bCap < pLen+bLen {
remSize := bCap - bLen
p = p[:remSize]
}
b.buf = append(b.buf, p...)
return pLen, nil
}
func cmdCombinedOutput(c *exec.Cmd) (data []byte, e error) {
if c.Stdout != nil {
return nil, errors.New("exec: Stdout already set")
}
if c.Stderr != nil {
return nil, errors.New("exec: Stderr already set")
}
b := newTruncateBuffer()
c.Stdout = b
c.Stderr = b
err := c.Run()
return b.buf, err
}
c.Stdout
、c.Stderr
为 io.Writer
,需要实现以下方法:
type Writer interface {
Write(p []byte) (n int, err error)
}
通过func newTruncateBuffer()
指定大小长度比直接在调用处make
更佳。
BenchMark测试
main_test.go
内容为:
func BenchmarkWrite2(b *testing.B) {
p := make([]byte, 512*1024)
rand.Read(p)
for n := 0; n < b.N; n++ {
b := NewBuffer1()
for i := 0; i < 10000; i++ {
b.Write2(p)
}
}
}
func BenchmarkWrite(b *testing.B) {
p := make([]byte, 512*1024)
rand.Read(p)
for n := 0; n < b.N; n++ {
b := NewBuffer1()
for i := 0; i < 10000; i++ {
b.Write(p)
}
}
}
main.go
内容为:
func (b *Buffer1) Write(p []byte) (n int, err error) {
pLen := len(p)
bLen := len(b.buf)
bCap := cap(b.buf)
if bCap == bLen {
return pLen, nil
} else if bCap < pLen+bLen {
remSize := bCap - bLen
p = p[:remSize]
}
b.buf = append(b.buf, p...)
return pLen, nil
}
func (b *Buffer1) Write2(p []byte) (n int, err error) {
pLen := len(p)
bLen := len(b.buf)
bCap := cap(b.buf)
if bCap <= pLen+bLen {
remSize := bCap - bLen
p = p[:remSize]
}
b.buf = append(b.buf, p...)
return pLen, nil
}
执行go test -bench=. -run=none main.go main_test.go
得到测试结果为:
goos: linux
goarch: amd64
cpu: AMD Ryzen 9 3950X 16-Core Processor
BenchmarkWrite2-32 6570 173257 ns/op
BenchmarkWrite-32 8100 148957 ns/op
PASS
ok command-line-arguments 4.276s