Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What is going on with this article?

More than 1 year has passed since last update.

@ktnyt

Goで空のスライスを作る時

Goにおける空スライスの作り方

Goでは空のスライスを作る方法が二種類あります。
型Typeについて
1. スライスリテラル記法による作成 []Type{}
2. Goのビルトイン関数による作成 make([]Type, 0)

正直どっちも対してやってることは変わらないだろうと思い習慣的に使っていたmakeによる作成をあらゆる場面で使っていました。というのも、makeはキャパシティ指定ができるので後からappendすることを想定した場合にキャパシティ確保分の時間をセーブできるだろうと思っていました。しかしある時にベンチマークを眺めているとruntime.mallocgcがやたらと時間を食っていたため掘っていくとmakeの行にたどり着いたため、「もしや」と思い空のスライスリテラルに書き換えてみたらパフォーマンスが改善しました。

ベンチマーク

こうなってくると実際にどの程度実行時に影響があるのかが気になります。そこで次のようなベンチマークを書いてみました。

func BenchmarkSliceAllocation(b *testing.B) {
    var p []byte

    b.Run("empty slice literal syntax", func(b *testing.B) {
        for i := 0; i < b.N; i++ {
            p = []byte{}
        }
    })

    func([]byte) {}(p)

    b.Run("make zero-length slice", func(b *testing.B) {
        for i := 0; i < b.N; i++ {
            p = make([]byte, 0)
        }
    })

    func([]byte) {}(p)
}
empty_slice_literal_syntax-4            161896716            0.765 ns/op
make_zero-length_slice-4                23673788             5.10 ns/op

実行してみてびっくり、なんと空のスライスリテラルはmakeの6倍以上早かったのです。

最適化に関してはド素人なのでこれ以上は掘ってないのですがそもそもキャパシティ付きでmakeする目的が間違ってたんだろうなという気持ちになりつつあります。
もし詳しい方がいたらご指摘いただけましたら幸いです。

5
Help us understand the problem. What is going on with this article?
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
5
Help us understand the problem. What is going on with this article?