Golangの文字列変数のコピーはO(1)

Go 言語の string は、他の多くの言語と違って nil にできない。string の「ゼロ値」(特定の値で初期化しない場合に格納されるデフォルトの内容)は空文字列だ。これを知ったとき、つい C++std::string を連想してしまい、「すると string 変数の代入は O(n) (高コスト)だったりしないか?」と少し気になってしまった。ということで、簡単な実験で検証してみた。

先に結論を書いておくと string 変数コピーのコストは O(1)、つまり内容の大きさに関わらず処理コストは一定で、心配無用だった。

以下、行った実験を備忘録。まず長い文字列データを生成して、以下の処理にかかる時間を比較:

  1. それを設定した文字列変数の全文字をスキャンする処理と、
  2. それを設定した文字列変数をコピーする処理と、
  3. (オマケで)文字列変数フィールドにそれを設定した構造体変数をコピーする処理。

これを、実験用文字列データの長さを 100 万文字から 1000 万文字まで増やしつつ、データ量と処理速度の関係を見る。

結果は以下のような感じで、スキャンする処理はデータ量に比例して処理時間が増加するものの、string 変数のコピー、string を含む構造体変数のコピーでは処理時間は増加しなかった。したがって変数コピー時に内容のコピーは発生しない模様:

f:id:sgryjp:20170902011616p:plain

ん、というか。文字列変数のコピーが平均 1 ナノ秒を切っている時点で、内容をコピーしているはずも無いか。THz (テラヘルツ)級の CPU でないと無理だもんね。まあ、ともあれ、間違いなく中身のコピーは発生していない。

実験用ソースは以下: