Help us understand the problem. What is going on with this article?

Goでは文字列連結はコストの高い操作

More than 5 years have passed since last update.

Goでは文字列は不変(immutable)なので、文字列への文字の追加は常に新しい文字列をアロケートすることになる。ランタイムはまず新しい文字列のためのメモリを割り当てて、そこに既存の文字列の内容をコピーし、新しい文字を最後に足すということを行う。

従って、文字列に+=演算子で文字列を追加していく操作は大変効率が悪い。Javaの文字列も同じだからJavaプログラマにとっては馴染みのある話だろうと思う。

文字列を構築する必要がある場合、[]byte型の値を作ってそれに文字列を追加していって、最後に値を文字列に変換するのがよい。

// サイズ0、内部バッファの長さ10の[]byteの値を割り当てる
b := make([]byte, 0, 10)

// bに文字列を追加
b = append(b, "foo"...) // ...が必要
b = append(b, "bar"...)
return string(b)

上のコードでは、10バイトのバッファを持った値bを最初に割り当てている。bは10バイトと短いのでスタックに割り付けられる(ヒープ割り当てよりスタック割り当てのほうが速いので、これはよいこと)。その後バッファを埋めていっているが、"foo"と"bar"は合わせて6バイトなのでbが再割り当てされることはない。従って上のコードでヒープにメモリが割り当てられるのは、最後に[]byteをstringに変換しているところだけになり、効率が良い。

もしバッファが途中で10バイトより長くなればbはヒープに移されるので、そういう文字列もきちんと構築することができる。

いずれにせよ文字列を連結するよりはこちらのほうが効率的なやり方だ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした