LoginSignup
1
0

More than 3 years have passed since last update.

構造体のsliceはポインタ定義しない方がハイパフォーマンス

Posted at

Goで構造体slice

Goの構造体sliceはいつもポインタで定義していましたが、
要素追加の時毎回allocationが走るので初期化時に構造体のsliceにした方がパフォーマンス的に良いそうです。

package main
import (
    "strconv"
    "testing"
)
type human struct {
    age  int
    name string
}
func BenchmarkPointerSlice(b *testing.B) {
    // 初期化時にslice分のメモリ容量を確保している
    people := make([]*human, 0, b.N)
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        people = append(people, &human{
            age:  i,
            name: strconv.Itoa(i),
        })
    }
}
func BenchmarkSlice(b *testing.B) {
    // ポインタ分の容量のみ確保している
    people := make([]human, 0, b.N)
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        // ここで毎回allocate
        people = append(people, human{
            age:  i,
            name: strconv.Itoa(i),
        })
    }
}

検証結果

~/.ghq/github.com/0daryo/playground  go test -bench . -benchmem
goos: darwin
goarch: amd64
pkg: github.com/0daryo/playground
BenchmarkPointerSlice-8         15123596                77.8 ns/op            39 B/op          1 allocs/op
BenchmarkSlice-8                46061704                28.7 ns/op             7 B/op          0 allocs/op
PASS
ok      github.com/0daryo/playground    3.471s
go test -bench . -benchmem  4.58s user 0.91s system 148% cpu 3.693 total

確かに実体の配列の方が3倍くらい速くてメモリ効率も良い
構造体のコピーコスト < allocation回数のコストだということだと思うのですが、オブジェクトサイズがあまりにも大きい場合はまた別問題かもしれません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0