LoginSignup
0
0

[翻訳転載] Golang Tip #3: パフォーマンスを考慮したスライスの初期化

Posted at

はじめに

本記事は以下のツイートの翻訳転載です。

スライスの初期化についての内容になります。

パフォーマンスを重視したスライスの初期化1

なぜパフォーマンスを考慮する必要があるのかについては次のPostを参照してください。

以前は、make(a, 10) を使って初期化していました。

が、結果的に先頭に意図しないゼロを大量に含んでしまうappend()(画像参照)を頻繁に手癖で書いてしまっていました。

これを避けるために、現在ではより効果的な初期化の方法である make(a, 0, 10) を使うようにしています。

image

おわりに

makeでのスライスの初期化について

Goのスライスには長さ(length)と容量(capacity)という概念が存在しています。

makeを使用してスライスを初期化する場合、make([type], [length], [capacity])のように指定します。

func main() {
	a := make([]int, 5)
	fmt.Printf("a (length: %d, capacity: %d)\n=> %v\n", len(a), cap(a), a)
	// a (length: 5, capacity: 5)
	// => [0 0 0 0 0]

	b := make([]int, 0, 5)
	fmt.Printf("b (length: %d, capacity: %d)\n=> %v\n", len(b), cap(b), b)
	// b (length: 0, capacity: 5)
	// => []

	c := make([]int, 0)
	fmt.Printf("c (length: %d, capacity: %d)\n=> %v\n", len(c), cap(c), c)
	// c (length: 0, capacity: 0)
	// => []
}

はじめから長さを持っているスライスにappendしてしまうと、初期化時の長さの分だけ先頭にゼロ(ゼロ値)を含むスライスができてしまうわけです。

JavaScriptでも同じような挙動になります。

const arr = Array.from({ length: 5 });

arr.push(5);

console.log(arr);
// [undefined, undefined, undefined, undefined, undefined, 5]

スライスの容量について

長さについてJavaScriptと比較しましたが、容量については、JavaScriptには無い概念です。

スライスの長さの変更に比べて、容量に変更が発生した場合の負荷は大きいです。

4人乗りの車を家族4人で乗り回してるうちは良いですが、家族が5人になってしまうと車自体を買い替えないといけないので大変です。

パフォーマンスを考慮すると、スライスの容量に変更がないように初期化するべきではあるのですが、

長さの変更に比べて負荷がかかるとはいえ、微々たるものではあるので、ごりごり開発を進める段階においてスライスの初期化は

func main() {
	var c []int
}

としておいて、
リリース前に余裕がある場合はリファクタすれば良し、余裕がなければ問題が顕在化するまで放置で良しで良いと思っています。

※例外的に、以下のような場合はmakeで長さと容量を指定した初期化を行います。

func main() {
	src := []int{1, 2, 3, 4, 5}
	dst := SliceMap(src, func(v int) string {
		return fmt.Sprintf("value: %d", v)
	})
	fmt.Printf("dst: %v\n", dst)
	// dst: [value: 1 value: 2 value: 3 value: 4 value: 5]
}

// SliceMap はJavaScriptのArray.prototype.mapのようなものです。
func SliceMap[E1 any, E2 any](src []E1, f func(E1) E2) []E2 {
	// スライスの長さと容量が明らかに決定している場合、かつスコープが短い場合はmakeを使う
	dst := make([]E2, len(src), cap(src))
	for i, v := range src {
		dst[i] = f(v)
	}
	return dst
}
  1. pre-allocation

0
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
0
0