No.95 スタックとヒープを理解していない
Go言語によれば変数がスタック割り当てかヒープ割り当てかは考える必要がない、とある
ただし最適化や処理速度を気にする場合はこのかぎりではない
以下の例では sumPtr における変数 z がスタック上に存在できないとコンパイラは判断する
変数 z はヒープへエスケープされる。関数のreturnのあとに変数が参照されないことをコンパイラが証明できないため
関数がポインタを返す際のこのような状況は sharing up と呼ばれたりする
スタックは自己クリーニングが行われるが、ヒープはGCによってクリーニングされなければならない
GCが実行されると利用可能なCPU容量の25%を使ってms単位の「ストップ・ザ・ワールド」を引き起こし遅延が発生 関連:
値レシーバ、ポインタレシーバでの違い。挙動が難しい
code:sumptr_test.go
package escape_test
import "testing"
var globalValue int
func sumPtr(x, y int) *int {
z := x + y
return &z
}
func sumVal(x, y int) int {
z := x + y
return z
}
func BenchmarkSumPtr(b *testing.B) {
b.ReportAllocs()
var local *int
var i int
for b.Loop() {
i++
local = sumPtr(i, i)
}
globalValue = *local
}
func BenchmarkSumVal(b *testing.B) {
b.ReportAllocs()
var local int
var i int
for b.Loop() {
i++
local = sumVal(i, i)
}
globalValue = local
}
code:log
goos: darwin
goarch: amd64
pkg: github.com/tkdn/go-sandbox/bench
cpu: Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz
BenchmarkSumPtr-8 66243919 15.40 ns/op 8 B/op 1 allocs/op
BenchmarkSumVal-8 564858717 2.153 ns/op 0 B/op 0 allocs/op
PASS
ok github.com/tkdn/go-sandbox/bench 2.672s