golangパフォーマンス2: slice vs array


テスト環境: go version go1.7.3 windows/amd64

ファイル構造:
rootファイル/02arraySlice.go
rootファイル/02arraySlice_test.go (効率テスト用)

02arraySlice.go

package go1_6

const capacity = 1024

//配列操作arrayはsliceにより早い
func array() [capacity]int {//配列処理テスト関数
    var d [capacity]int

    for i := 0; i < len(d); i++ {
        d[i] = 1
    }

    return d
}

func slice() []int {//slice処理テスト関数
    d := make([]int, capacity)

    for i := 0; i < len(d); i++ {
        d[i] = 1
    }

    return d
}

//パラメータとして渡す場合はsliceほうが早い (arrayはメモリ中にコピーされる)
func inArray(array [capacity]int) {//配列として関数パラメータ効率テスト

}

func inArray2(array *[capacity]int) {//配列ポインタとして関数パラメータ効率テスト

}

func inSlice(slice []int) {//sliceとして関数パラメータ効率テスト

}

//reArrayにより早い
func reSlice() []byte {//return slice場合効率テスト
    return []byte{1, 2, 3, 4}
}

func reArray() [4]byte {//return array場合効率テスト
    return [4]byte{1, 2, 3, 4}
}

02arraySlice_test.go

package go1_6

import (
    "testing"
)

func BenchmarkArray(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = array()
    }
}

func BenchmarkSlice(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = slice()
    }

}

func BenchmarkInArray(b *testing.B) {
    arr := array()
    for i := 0; i < b.N; i++ {
        inArray(arr)
    }
}

func BenchmarkInArray2(b *testing.B) {
    b.StopTimer()
    arr := array()
    b.StartTimer()

    parr := &arr
    for i := 0; i < b.N; i++ {
        inArray2(parr)
    }
}

func BenchmarkInSlice(b *testing.B) {
    b.StopTimer()
    sli := slice()
    b.StartTimer()

    for i := 0; i < b.N; i++ {
        inSlice(sli)
    }

}

func BenchmarkReArray(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = reArray()
    }
}

func BenchmarkReSlice(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = reSlice()
    }
}

テスト結果:

ポイント:
通常処理場合は配列がSliceにより早いですが、
配列は関数パラメータと関数戻し値として利用された場合は
メモリ中にコピーされるため逆に効率が落ちます。