3 回答

TA貢獻(xiàn)1757條經(jīng)驗(yàn) 獲得超7個(gè)贊
設(shè)置 GOGC=off 提高了性能(降低到小于 100 毫秒)。為什么?因?yàn)?a >逃逸分析。當(dāng)您使用go build -gcflags -m
編譯器構(gòu)建時(shí),會(huì)打印任何逃逸到堆的分配。這實(shí)際上取決于您的機(jī)器和 GO 編譯器版本,但是當(dāng)編譯器決定分配應(yīng)該移到堆時(shí),這意味著兩件事:1. 分配將花費(fèi)更長的時(shí)間(因?yàn)槎褩I系摹胺峙洹敝皇?1 個(gè) cpu 指令)2. GC 稍后將不得不清理該內(nèi)存 - 為我的機(jī)器花費(fèi)更多的 CPU 時(shí)間,65536 字節(jié)的分配轉(zhuǎn)義到堆,而 65535 則不會(huì)。這就是為什么 1 個(gè)字節(jié)將整個(gè)過程從 200 毫秒更改為 30 秒的原因。驚人..

TA貢獻(xiàn)1806條經(jīng)驗(yàn) 獲得超8個(gè)贊
注意/2021 年更新:正如Tapir Liui在Go101中用這條推文指出的那樣:
從 Go 1.17 開始,如果編譯器證明它們僅在當(dāng)前 goroutine 中使用,并且Go 運(yùn)行時(shí)將在堆棧上分配slice 的元素:xN <= 64KB
var x = make([]byte, N)
如果編譯器證明它僅用于當(dāng)前 goroutine并且 Go 運(yùn)行時(shí)將在堆棧上分配數(shù)組 :yN <= 10MB
var y [N]byte
那么如何分配的(的元素)片,其尺寸大于64KB上堆疊更大但不大于10MB(和切片僅在一個(gè)夠程中使用)?
只需使用以下方式:
var y [N]byte
var x = y[:]
考慮到堆棧分配比堆分配快,這將對您的測試產(chǎn)生直接影響,因?yàn)閍lloc等于 65536 或更多。
貘補(bǔ)充說:
事實(shí)上,我們可以在堆棧上分配具有任意總和元素大小的切片。
const N = 500 * 1024 * 1024 // 500M
var v byte = 123
func createSlice() byte {
var s = []byte{N: 0}
for i := range s { s[i] = v }
return s[v]
}
將 500 更改為 512 會(huì)使程序崩潰。

TA貢獻(xiàn)1776條經(jīng)驗(yàn) 獲得超12個(gè)贊
原因很簡單。
const alloc int = 65535
0x0000 00000 (example.go:8) TEXT "".main(SB), ABIInternal, $65784-0
const alloc int = 65536
0x0000 00000 (example.go:8) TEXT "".main(SB), ABIInternal, $248-0
不同之處在于切片的創(chuàng)建位置。
- 3 回答
- 0 關(guān)注
- 259 瀏覽
添加回答
舉報(bào)