Go Wiki:編譯器和執行時期最佳化
此頁面列出編譯器執行的最佳化。請注意,這些最佳化並未由語言規格保證。
介面值
介面值中的零寬度型別
在介面值中放置零寬度型別不會配置。
- gc 1.0+
- gccgo ?
介面值中的字元大小值
在介面值中放置字元大小或更小的非指標型別不會配置。
- gc: 1.0-1.3,但不在 1.4+
- gccgo: 永不
string
和 []byte
使用 []byte
查詢映射
對於型別為 map[string]T
的映射 m
和 []byte b
,m[string(b)]
不會配置。(不會建立暫時字串複製的位元組切片)
- gc 1.4+
- gccgo ?
range
遍歷 []byte
(s)
將 string
轉換為 []byte
以遍歷位元組時不會配置
s := "foo"
for i, c := range []byte(s) {
// ...
}
用於字串比較的轉換
將 []byte
轉換為 string
以進行比較時不會配置
var b1 string
var b2 []byte
var x = string(b1) == string(b2) // memeq
var y = string(b1) < string(b2) // lexicographical comparison
- gc: 1.5+(CL 3790)
- gccgo ?
逸出分析和內嵌
使用 -gcflags -m
來觀察 gc 工具鏈的逸出分析和內嵌決策結果。
(待辦事項:說明 -gcflags -m
的輸出)
逸出分析
Gc 編譯器會跨函式和套件邊界執行全域逸出分析。然而,在許多情況下它會放棄。例如,指定給任何間接類型的任何內容(*p = ...
)都被視為逸出。其他可能抑制分析的事項有:函式呼叫、套件邊界、切片文字、子切片和索引等。完整的規則過於複雜,無法描述,因此請查看 -m
輸出。
- gc 1.0+
- gccgo 8.0+.
函式內嵌
只有短而簡單的函式會內嵌。函式必須符合以下規則才能內嵌
- 函式必須夠簡單,AST 節點數量必須低於預算 (80);
- 函式不包含封閉、遞延、復原、選擇等複雜內容;
- 函式沒有 go:noinline 前綴;
- 函式沒有 go:uintptrescapes 前綴,因為在內嵌期間會遺失逃逸資訊;
- 函式有主體;
- 等等。
- gc 1.0+
- gccgo:-O1 以上。
慣用語
最佳化 memclr
對於區塊或陣列 s,下列形式的迴圈
for i := range s {
s[i] = <zero value for element of s>
}
會轉換成有效率的執行時期 memclr 呼叫。問題 和 提交。
- gc 1.5+
- gccgo ?
不可掃描物件
當元素類型不包含指標時 (對應映射的 key 和 value),垃圾收集器不會掃描區塊、通道和映射的底層緩衝區。這允許在記憶體中保留大型資料集,而不會在垃圾收集期間付出高昂代價。例如,以下映射不會明顯影響 GC 時間
type Key [64]byte // SHA-512 hash
type Value struct {
Name [32]byte
Balance uint64
Timestamp int64
}
m := make(map[Key]Value, 1e8)
- gc 1.5+
- gccgo ?
此內容是 Go Wiki 的一部分。