Golang byte接合方法の性能比較
31232 ワード
Golang byte接合方法の性能比較
最近、プロジェクトで[]Byteをつなぎ合わせる必要があることに遭遇し、[]Byteをつなぎ合わせる様々な方法を比較し、テストコードは以下の通りである.
package main
import (
"bytes"
"fmt"
"time"
)
func main() {
count := 1000000
oneSerail := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s0 := time.Now()
for i := 0; i < count; i++ {
str0 := make([][]byte, 8)
str0[0] = oneSerail[0:4]
str0[1] = oneSerail[4:6]
str0[2] = oneSerail[6:10]
str0[3] = oneSerail[0:2]
str0[4] = oneSerail[2:6]
str0[5] = oneSerail[6:8]
str0[6] = oneSerail[0:4]
str0[7] = oneSerail[8:10]
bytes.Join(str0, []byte(""))
}
e0 := time.Now()
d0 := e0.Sub(s0)
fmt.Printf("time of way(0)=%v
", d0)
s1 := time.Now()
for i := 0; i < count; i++ {
str1 := make([]byte, 0)
str1 = append(str1, oneSerail[0])
str1 = append(str1, oneSerail[1])
str1 = append(str1, oneSerail[2])
str1 = append(str1, oneSerail[3])
str1 = append(str1, oneSerail[4])
str1 = append(str1, oneSerail[5])
str1 = append(str1, oneSerail[6])
str1 = append(str1, oneSerail[7])
str1 = append(str1, oneSerail[8])
str1 = append(str1, oneSerail[9])
str1 = append(str1, oneSerail[0])
str1 = append(str1, oneSerail[1])
str1 = append(str1, oneSerail[2])
str1 = append(str1, oneSerail[3])
str1 = append(str1, oneSerail[4])
str1 = append(str1, oneSerail[5])
str1 = append(str1, oneSerail[6])
str1 = append(str1, oneSerail[7])
str1 = append(str1, oneSerail[8])
str1 = append(str1, oneSerail[9])
str1 = append(str1, oneSerail[0])
str1 = append(str1, oneSerail[1])
str1 = append(str1, oneSerail[2])
str1 = append(str1, oneSerail[3])
str1 = append(str1, oneSerail[4])
str1 = append(str1, oneSerail[5])
str1 = append(str1, oneSerail[6])
str1 = append(str1, oneSerail[7])
str1 = append(str1, oneSerail[8])
str1 = append(str1, oneSerail[9])
}
e1 := time.Now()
d1 := e1.Sub(s1)
fmt.Printf("time of way(1)=%v
", d1)
s2 := time.Now()
for i := 0; i < count; i++ {
str2 := make([]byte, 0)
str2 = append(str2, oneSerail[0:4]...)
str2 = append(str2, oneSerail[4:6]...)
str2 = append(str2, oneSerail[6:10]...)
str2 = append(str2, oneSerail[0:2]...)
str2 = append(str2, oneSerail[2:6]...)
str2 = append(str2, oneSerail[6:8]...)
str2 = append(str2, oneSerail[0:4]...)
str2 = append(str2, oneSerail[4:8]...)
str2 = append(str2, oneSerail[8:10]...)
}
e2 := time.Now()
d2 := e2.Sub(s2)
fmt.Printf("time of way(2)=%v
", d2)
s3 := time.Now()
for i := 0; i < count; i++ {
str3 := make([]byte, 30)
for j := 0; j < 30; j++ {
str3[j] = oneSerail[j%10]
}
}
e3 := time.Now()
d3 := e3.Sub(s3)
fmt.Printf("time of way(3)=%v
", d3)
s4 := time.Now()
for i := 0; i < count; i++ {
var buf bytes.Buffer
for j := 0; j < 3; j++ {
buf.Write(oneSerail)
}
//fmt.Println(buf.Bytes())
}
e4 := time.Now()
d4 := e4.Sub(s4)
fmt.Printf("time of way(4)=%v
", d4)
}
実行結果は次のとおりです.
time of way(0)=194.6382ms
time of way(1)=186.6535ms
time of way(2)=136.7474ms
time of way(3)=65.876ms
time of way(4)=107.3008ms
結果分析:1,bytes.Joinが最も時間がかかるのは、Joinを行う際に再メモリ割り当てが必要になるためかもしれません.2,単一byteでappendを行うにはbytesより時間がかかる.Joinは短いが、限られている.3,[]byte...appendを行う時間は1と2より短い.append操作の回数は2よりずっと少ないからだ.4,最も速い方法ですが、接合後のbyteグループの大きさを予知する必要があります.5、さっき文章を見たばかりで、bytes.Bufferがつなぎ合わせる.この方法は,接合後のbyte群長が既知の場合,4速ではないが,未知のbyte群長の場合,1,2,3よりも速いことが利点である.
まとめ:golangのメモリ割り当ては本当に時間がかかります.