Go Wiki:コンパイラとランタイムの最適化

このページでは、コンパイラによって行われる最適化についてリストしています。これらの最適化は、言語仕様によって保証されているものではないことに注意してください。

インターフェース値

インターフェース値におけるゼロ幅型

ゼロ幅型をインターフェース値に入れると、メモリは割り当てられません。

インターフェース値におけるワードサイズの値

ワードサイズ以下の非ポインタ型をインターフェース値に入れると、メモリは割り当てられません。

string[]byte

[]byteによるマップのルックアップ

map[string]T型のマップm[]byte bの場合、m[string(b)]ではメモリは割り当てられません。(バイトスライスの一時的な文字列コピーは作成されません)

[]byterangeループ

string[]byteに変換してバイトをループ処理する場合、メモリは割り当てられません。

s := "foo"
for i, c := range []byte(s) {
    // ...
}

文字列比較のための変換

比較のために[]bytestringに変換する場合、メモリは割り当てられません。

var b1 string
var b2 []byte
var x = string(b1) == string(b2) // memeq
var y = string(b1) < string(b2)  // lexicographical comparison

エスケープ解析とインライン化

gcツールチェーンのエスケープ解析とインライン化の決定の結果を確認するには、-gcflags -mを使用します。

(TODO: -gcflags -mの出力について説明する)

エスケープ解析

Gcコンパイラは、関数とパッケージの境界を越えてグローバルなエスケープ解析を行います。ただし、解析を断念するケースが多数あります。たとえば、間接参照に代入されたもの(*p = ...)は、エスケープすると見なされます。解析を妨げる可能性のあるものとしては、関数呼び出し、パッケージの境界、スライスのリテラル、サブスライシングとインデックス付けなどがあります。完全なルールは複雑すぎるため説明できません。-mの出力を確認してください。

関数インライン化

短くて単純な関数のみがインライン化されます。インライン化されるには、関数は次のルールに従う必要があります。

イディオム

最適化されたmemclr

スライスまたは配列sの場合、次の形式のループ

for i := range s {
    s[i] = <zero value for element of s>
}

は、効率的なランタイムmemclr呼び出しに変換されます。Issuecommit

スキャン不可能なオブジェクト

要素型にポインタが含まれていない場合(マップの場合はキーと値の両方)、ガベージコレクタはスライス、チャネル、マップの基礎となるバッファをスキャンしません。これにより、ガベージコレクション中に高いコストを支払うことなく、大量のデータセットをメモリに保持できます。たとえば、次のマップはGC時間に目に見える影響を与えません。

type Key [64]byte // SHA-512 hash
type Value struct {
    Name      [32]byte
    Balance   uint64
    Timestamp int64
}
m := make(map[Key]Value, 1e8)

このコンテンツはGo Wikiの一部です。