はじめに
Goで関数のパフォーマンスを測ってみたいと思い、調べて使ってみました。
コード
文字列をループで回して結合する関数
stringsのJoinで結合する関数
どちらのほうがパフォーマンスがいいか計測してみます。
package main
import "strings"
func ConcatenateStrings(strs []string) string {
var result string
for _, str := range strs {
result += str
}
return result
}
func JoinStrings(strs []string) string {
return strings.Join(strs, "")
}
func main() {
// main関数には実行コードがなくても大丈夫です
}
ここでは、1000個の配列テストデータを作成して、それを対象関数に渡しています。
testing.Bがベンチマーク用のパッケージになります。
package main
import (
"testing"
)
func generateTestData(n int) []string {
strs := make([]string, n)
for i := 0; i < n; i++ {
strs[i] = "test"
}
return strs
}
func BenchmarkConcatenateStrings(b *testing.B) {
strs := generateTestData(1000)
for i := 0; i < b.N; i++ {
ConcatenateStrings(strs)
}
}
func BenchmarkJoinStrings(b *testing.B) {
strs := generateTestData(1000)
for i := 0; i < b.N; i++ {
JoinStrings(strs)
}
}
動かしてみる
3105や141476は、実行した回数
ns/opは、1回あたりの実行に掛かったナノ秒
B/opは、1回あたりのアロケーションで確保したメモリ容量
allocs/opは、1回あたりのアロケーション回数
go test -bench=. -benchmem
実行速度的にもメモリ的にも、strings.Join()の方が優秀ということが分かった。
goos: darwin
goarch: amd64
pkg: github.com/xxxxx/xxxxx
cpu: Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
BenchmarkConcatenateStrings-4 3105 402025 ns/op 2137578 B/op 999 allocs/op
BenchmarkJoinStrings-4 141476 7990 ns/op 4096 B/op 1 allocs/op
PASS
ok github.com/xxxxx/xxxxx 3.652s