未知の量のデータをバイトのスライスに追加する必要がある状況では、ループ内で組み込み関数append()
を使用するか、新しいBuffer
を作成することができますWrite()
機能を使用してください。Builtin append with bytes.Buffer write
どの方法が最速ですか?以下のベンチマークによって示されるように、組み込み関数append
を使用して
未知の量のデータをバイトのスライスに追加する必要がある状況では、ループ内で組み込み関数append()
を使用するか、新しいBuffer
を作成することができますWrite()
機能を使用してください。Builtin append with bytes.Buffer write
どの方法が最速ですか?以下のベンチマークによって示されるように、組み込み関数append
を使用して
それはケースを使用することによって決まります。
どちらの場合もbytes.Buffer
はappend
(サンプル:1,2,3,4)より高速です。
buf = append(buf, make([]byte, 16)...)
が6.6623811s
を取る使用して、buf.Write(make([]byte, 16))
が4.6482659s
を取る
を使用します。サンプル5、6のために
:
buf = append(buf, byte(i))
を使用すると、445.0255ms
をとり、
buf.WriteByte(byte(i))
を使用すると、組み込み関数copy
を使用し、それが高速です1.4410824s
そしてbytes.Buffer
を取ります
//書き込みpの内容をバッファに追加し、バッファを増やす をとします。 //必要です。戻り値nはpの長さです。エラーは常に です。
//バッファが大きくなりすぎると、書き込みは ErrTooLargeでパニックになります。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.8892797sをとり、append
7をとります。7514434s
は、これらのベンチマークを参照してくださいappend
を使用
1-:
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))
}
出力:bytes.Buffer
7.7514434s
1600000000
2-
出力:bytes.Buffer
を使用
4.8892797s
1600000000
3- make([]byte, 16)
有する:append
を使用
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
}
4- make([]byte, 16)
有する:
5- 445.0255ms
かかり:
package main
import (
"bytes"
"fmt"
"time"
)
func main() {
buf := &bytes.Buffer{}
t := time.Now()
for i := 0; i < 100000000; i++ {
buf.WriteByte(byte(i))
}
fmt.Println(time.Since(t)) // 1.4410824s
fmt.Println(buf.Len()) // 100000000
}
および参照:
package main
import (
"fmt"
"time"
)
func main() {
buf := []byte{}
t := time.Now()
for i := 0; i < 100000000; i++ {
buf = append(buf, byte(i))
}
fmt.Println(time.Since(t)) // 445.0255ms
fmt.Println(len(buf)) // 100000000
}
6- buf.WriteByte(byte(i))
を使用するが1.4410824s
かかり
Appending to slice bad performance.. why?
Where is append() implementation?
Efficient appending to a variable-length container of strings (Golang)
2つの答えから異なる結果を見て、自分のニーズに応じて自分自身を作成しようとしました:https://play.golang.org/p/kyuX5qzaIG。結果はappendが最も速いことを示します(append = 2.70 ns/op、bufferWrite = 9.32 ns/op)。何とかベンチに問題があるはずです。 –
@WilliamPoussier:Tim Cooperのfunc: 'randomSlice'での返答' return byte(0)、rand.Intn()の代わりにreturn make([]バイト、rand.Intn(1 << 10) 1 << 10)) '長さがゼロのスライスを使用すると良いベンチマークではありません。 –
本当にあなたは正しいです。私がテストデータによって空でないスライスに変更したとき、appendはバッファを使うよりも遅いです。 –
は、高速です:
package x
import (
"bytes"
"math/rand"
"testing"
"time"
)
var startSeed = time.Now().UnixNano()
func randomSlice() []byte {
return make([]byte, 0, rand.Intn(1<<10))
}
func BenchmarkAppend(b *testing.B) {
rand.Seed(startSeed)
b.ResetTimer()
var all []byte
for i := 0; i < b.N; i++ {
all = append(all, randomSlice()...)
}
}
func BenchmarkBufferWrite(b *testing.B) {
rand.Seed(startSeed)
b.ResetTimer()
var buff bytes.Buffer
for i := 0; i < b.N; i++ {
buff.Write(randomSlice())
}
all := buff.Bytes()
_ = all
}
結果:
BenchmarkAppend-4 10000000 206 ns/op 540 B/op 0 allocs/op
BenchmarkBufferWrite-4 10000000 214 ns/op 540 B/op 0 allocs/op
組み込み関数は、任意の代替よりも一般的に高速です。私は追加がこの場合にはより速くなると思います – Sridhar