golang スライスの拡張の仕組みとは
Go言語におけるスライス(slice)は、動的配列の抽象です。スライスの長さは、必要に応じて自動的に拡張することができ、拡張の仕組みは、より大きな基底配列を作成し、元のデータを新しい配列にコピーすることによって実現されます。
配列の基底となるスライスは、メモリ内に連続的に割り当てられた領域ですが、スライスの容量が新しい要素を格納するには十分でない場合は、拡張する必要があります。これは、次のプロセスで行われます。
- スライス容量が十分かどうかまず確認する。容量あれば、スライス末尾に要素を追加して、スライス長を更新する。
- 容量不足の際にはGo言語はスライスの長さ並びに容量の関係に基づき、新たな容量を計算します。通常、新たな容量の値は元の容量の2倍になりますが、元の容量が大きい場合(1024を超える)は、新たな容量の増加戦略は元の容量の1.25倍となります。
- 元のデータを新しい配列にコピーするために、新しい基底配列を新しい容量の長さで作成する。
- ポインタ、長さ、容量のスライスを更新し、新しい基盤配列を指すようにします。
- 最後に、スライスの末尾に要素を追加します。
スライス容量の拡張は自動処理され、開発者からは不可視です。基盤となる配列はメモリ内に連続的に割り当てられるため、スライスを拡張すると、基盤となる配列の再割り当てとデータの複製が発生する可能性があります。これには一定のパフォーマンスコストが伴います。そのため、スライスを使用する場合は、スライスの容量を事前に推定し、適切なタイミングで拡張を実行し、基盤となる配列の再割り当て回数を減らしてパフォーマンスを向上させる必要があります。