簡體   English   中英

當golang分配字符串到字節的轉換時

[英]When golang does allocation for string to byte conversion

var testString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
//var testString = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
func BenchmarkHashing900000000(b *testing.B){
    var bufByte = bytes.Buffer{}
    for i := 0; i < b.N ; i++{
        bufByte.WriteString(testString)
        Sum32(bufByte.Bytes())
        bufByte.Reset()
    }
}

func BenchmarkHashingWithNew900000000(b *testing.B){
    for i := 0; i < b.N ; i++{
        bytStr := []byte(testString)
        Sum32(bytStr)
    }
}

測試結果:

With  testString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
BenchmarkHashing900000000-4         50000000            35.2 ns/op         0 B/op          0 allocs/op
BenchmarkHashingWithNew900000000-4  50000000            30.9 ns/op         0 B/op          0 allocs/op

With testString = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
BenchmarkHashing900000000-4         30000000            46.6 ns/op         0 B/op          0 allocs/op
BenchmarkHashingWithNew900000000-4  20000000            73.0 ns/op        64 B/op          1 allocs/op

如果string長,為什么在BenchmarkHashingWithNew900000000情況下有分配,而string小時為什么沒有分配。
Sum32: https ://gowalker.org/github.com/spaolacci/murmur3
我正在使用go1.6

您的基准測試正在觀察Golang編譯器(版本1.8)的奇怪優化。

您可以在此處查看Dmitry Dvyukov的PR

https://go-review.googlesource.com/c/go/+/3120

不幸的是,這是很久以前的事情,當時使用C語言編寫編譯器時,我不確定在當前的編譯器中哪里可以找到優化。 但是我可以確認它仍然存在,並且Dmitry的PR描述是准確的。

如果您想要一組更清晰的自包含基准來證明這一點,我這里有一個要點。

https://gist.github.com/fmstephe/f0eb393c4ec41940741376ab08cbdf7e

如果僅查看第二個基准BenchmarkHashingWithNew900000000我們可以清楚地看到它應該“分配”的位置。

bytStr := []byte(testString)

該行必須將testString的內容復制到新的[]byte 然而,在這種情況下,編譯器可以看到bytStr從未之后再次使用Sum32的回報。 因此,可以在堆棧上分配它。 但是,由於字符串可以任意大,所以將堆棧分配的string[]byte的限制設置為32個[]byte

值得一提的是這個小技巧,因為如果基准字符串都很短,很容易就讓自己相信一些代碼沒有分配。

當您將某些內容寫入byte.Buffer ,它將根據需要分配內存。 當您調用byte.Buffer.Reset ,不會釋放該內存,而是將其保留以供以后重用。 而您的代碼正是這樣做的。 它將緩沖區標記為空,然后再次填充。

其實, 一些分配的事,但迭代5000次的時候,實在是微不足道。 但是,如果將bufByte的聲明bufByte for循環中,則會得到一些分配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM