Go1.6 パフォーマンスについて
Go1.6リリース!
去る2016/02/17にGoの1.6がリリースされました。 という訳で色々試してみようと思ったのですが、やりたかったことのほぼ100%を すでにRC版で実施されている方がいましたので有難く内容拝見させて頂きました。 良記事オススメです。 qiita.com
Go1.6 パフォーマンス周りの変更点
上の記事を読んで終わりにしてもアレなので、パフォーマンスに関して少し詳しく触れてみます。
変更点
As always, the changes are so general and varied that precise statements about performance are difficult to make. Some programs may run faster, some slower. On average the programs in the Go 1 benchmark suite run a few percent faster in Go 1.6 than they did in Go 1.5. The garbage collector's pauses are even lower than in Go 1.5, especially for programs using a large amount of memory.
プログラムの作りによって速くなったり遅くなったりだが、1.5に比べて平均数%速度改善し、 GCによるプログラムの停止時間が1.4 => 1.5からさらに短縮されたよ!とのことです。ふむふむ。
There have been significant optimizations bringing more than 10% improvements to implementations of the compress/bzip2, compress/gzip, crypto/aes, crypto/elliptic, crypto/ecdsa, and sort packages.
compress/bzip2
compress/gzip
crypto/aes
sort
あたりに10%以上の速度改善を行ったとのこと。
特に sort
は日頃から使う機会が多いので気になるところ。ということでベンチを取ってみます。
尚、動作検証時のバージョン切り替えにはgvmを使用しました。
sortパッケージの速度比較
package bench_test import ( "math/rand" "sort" "testing" "time" ) func BenchmarkSort(b *testing.B) { n := 1000 l := make([]int, n) for i := 0; i < n; i++ { rand.Seed(time.Now().UnixNano() + int64(i)) l[i] = rand.Intn(n) } b.ResetTimer() for i := 0; i < b.N; i++ { ll := make([]int, n) copy(ll, l) sort.Sort(sort.IntSlice(ll)) } }
1.5.3
BenchmarkSort-5 10000 122986 ns/op 8224 B/op 2 allocs/op
1.6
BenchmarkSort-5 10000 109763 ns/op 8224 B/op 2 allocs/op
確かに10%程改善しています。
Go1.6 におけるパフォーマンスチューニング
Goのパフォーマンスチューニングと言えば、超良記事であるこちら。 qiita.com
こちらの内容が1.6になったことで何か変化があるのかついでに確認してみました。 (テストコード拝借させていただきました)
1.5.3
BenchmarkMemAllocOndemand-5 2000000 650 ns/op 496 B/op 5 allocs/op BenchmarkMemAllocAllBeforeUsing-5 10000000 154 ns/op 160 B/op 1 allocs/op BenchmarkFillSliceByAppend-5 5000000 342 ns/op 896 B/op 1 allocs/op BenchmarkFillSliceByIndex-5 5000000 273 ns/op 896 B/op 1 allocs/op BenchmarkExclusiveWithChannel-5 20000000 69.9 ns/op 0 B/op 0 allocs/op BenchmarkExclusiveWithMutex-5 100000000 20.1 ns/op 0 B/op 0 allocs/op BenchmarkSyncWithChannel-5 300000 4132 ns/op 0 B/op 0 allocs/op BenchmarkSyncWithWaitGroup-5 1000000 2019 ns/op 0 B/op 0 allocs/op BenchmarkStringMatchWithRegexp-5 3000000 430 ns/op 0 B/op 0 allocs/op BenchmarkStringMatchWithoutRegexp-5 50000000 38.5 ns/op 0 B/op 0 allocs/op BenchmarkGoroutine-5 1000000 2015 ns/op 0 B/op 0 allocs/op BenchmarkSequential-5 10000000 187 ns/op 0 B/op 0 allocs/op BenchmarkLenDirect-5 2000000 926 ns/op 0 B/op 0 allocs/op BenchmarkLenCached-5 2000000 919 ns/op 0 B/op 0 allocs/op
1.6
BenchmarkMemAllocOndemand-5 2000000 672 ns/op 496 B/op 5 allocs/op BenchmarkMemAllocAllBeforeUsing-5 10000000 156 ns/op 160 B/op 1 allocs/op BenchmarkFillSliceByAppend-5 5000000 360 ns/op 896 B/op 1 allocs/op BenchmarkFillSliceByIndex-5 5000000 333 ns/op 896 B/op 1 allocs/op BenchmarkExclusiveWithChannel-5 20000000 67.9 ns/op 0 B/op 0 allocs/op BenchmarkExclusiveWithMutex-5 100000000 20.0 ns/op 0 B/op 0 allocs/op BenchmarkSyncWithChannel-5 500000 3857 ns/op 0 B/op 0 allocs/op BenchmarkSyncWithWaitGroup-5 1000000 1994 ns/op 0 B/op 0 allocs/op BenchmarkStringMatchWithRegexp-5 3000000 409 ns/op 0 B/op 0 allocs/op BenchmarkStringMatchWithoutRegexp-5 50000000 39.0 ns/op 0 B/op 0 allocs/op BenchmarkGoroutine-5 1000000 2008 ns/op 0 B/op 0 allocs/op BenchmarkSequential-5 10000000 185 ns/op 0 B/op 0 allocs/op BenchmarkLenDirect-5 2000000 918 ns/op 0 B/op 0 allocs/op BenchmarkLenCached-5 2000000 937 ns/op 0 B/op 0 allocs/op
大きな差異は見られません。触れ込み通り速くなったり遅くなったりって感じですね。 ただし、チューニングの効果に関してはどちらのバージョンも一緒のようです。
というわけでこれまで通りの考え方で良さそうですね。
まとめ
上記以外にも何本か既存の1.5系で書いたプログラムのテストを走らせたりしてみましたが、 特に問題は発生しませんでした。1.4 => 1.5の時もそうでしたが、今回も割とカジュアルに移行できそうな印象です。
ただし、今回は触れませんでしたがmapへの読み書きをgoroutine safeに扱ってなかったりするとpanicするという
結構ドキドキな変更が入っていたりもしますので、、移行前に一度-race
を付けてテストを実施することをお勧めします (^^;)