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のメモリ割り当ては本当に時間がかかります.