Wil*_*ier 7 performance buffer byte go
在我需要将未知数量的数据添加到字节切片的情况下,比如在循环中,我可以使用内置函数append()或创建一个新函数Buffer并使用该Write()函数。
哪种方法最快?
小智 9
这取决于用例。
这里在这两种情况下bytes.Buffer都比append(Samples: 1, 2, 3, 4)快。
使用buf.Write(make([]byte, 16))拍摄4.6482659s,
使用buf = append(buf, make([]byte, 16)...)拍摄6.6623811s。
对于示例 5、6:
使用buf = append(buf, byte(i))take 445.0255ms、
Using buf.WriteByte(byte(i))take1.4410824s
并bytes.Buffer使用内置函数copy,速度很快:
// Write 将 p 的内容附加到缓冲区,
根据需要增加缓冲区// 。返回值 n 是 p 的长度;错误始终为零。
//如果缓冲区变得太大,Write 将因 ErrTooLarge 而出现恐慌。Run Code Online (Sandbox Code Playgroud)func (b *Buffer) Write(p []byte) (n int, err error) { b.lastRead = opInvalid m := b.grow(len(p)) return copy(b.buf[m:], p), nil }
bytes.Buffer需要 4.8892797sappend需要 7.7514434s
请参阅这些基准:
1-使用append:
func (b *Buffer) Write(p []byte) (n int, err error) {
b.lastRead = opInvalid
m := b.grow(len(p))
return copy(b.buf[m:], p), nil
}
Run Code Online (Sandbox Code Playgroud)
输出:
7.7514434s
1600000000
Run Code Online (Sandbox Code Playgroud)
2- 使用 bytes.Buffer
package main
import (
"fmt"
"time"
)
func main() {
buf := []byte{}
data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
t := time.Now()
for i := 0; i < 100000000; i++ {
buf = append(buf, data...)
}
fmt.Println(time.Since(t))
fmt.Println(len(buf))
}
Run Code Online (Sandbox Code Playgroud)
输出:
4.8892797s
1600000000
Run Code Online (Sandbox Code Playgroud)
3-使用bytes.Buffer具有make([]byte, 16):
7.7514434s
1600000000
Run Code Online (Sandbox Code Playgroud)
4-使用append用make([]byte, 16):
package main
import (
"bytes"
"fmt"
"time"
)
func main() {
buf := &bytes.Buffer{}
data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
t := time.Now()
for i := 0; i < 100000000; i++ {
buf.Write(data)
}
fmt.Println(time.Since(t))
fmt.Println(buf.Len())
}
Run Code Online (Sandbox Code Playgroud)
5- 使用buf = append(buf, byte(i))take 445.0255ms:
4.8892797s
1600000000
Run Code Online (Sandbox Code Playgroud)
6- 使用buf.WriteByte(byte(i))take 1.4410824s:
package main
import (
"bytes"
"fmt"
"time"
)
func main() {
buf := &bytes.Buffer{}
t := time.Now()
for i := 0; i < 100000000; i++ {
buf.Write(make([]byte, 16))
}
fmt.Println(time.Since(t)) // 4.6482659s
fmt.Println(buf.Len()) //1600000000
}
Run Code Online (Sandbox Code Playgroud)
并看到:
附加到切片糟糕的性能..为什么?
append() 实现在哪里?
高效附加到可变长度的字符串容器(Golang)