概要
こちらは、https://qiita.com/advent-calendar/2018/gopherdojo の25日目の記事です。
普段は、Rubyでサーバー開発します、たまにStackProfを使ってrubyプログラムのプロファイリングします
Goで触ってみたとき、プロファイラ便利なツールがあるか気になるので、一応調べて書きました。
Go 環境
- Go ver1.11.2
- MacOS
Go Profileは二つの取り方がある
-
https://golang.org/pkg/runtime/pprof/
- ファイルに出力してプロファイリングする。一発終わるコマンドで使えそう。
-
https://golang.org/pkg/net/http/pprof/
- httpサーバー経由でプロファイリングする。Webサービスで使えそう
環境準備
-
github.com/pkg/profile
をダンロードする
go get github.com/pkg/profile
- graphvizをインストールする
brew install graphviz
runtime/pprof
Step1: コードにプロファイラを埋め込む
package main
import (
"fmt"
"github.com/pkg/profile"
)
func fib(n int) int {
if n < 2 {
return n
}
return fib(n-1) + fib(n-2)
}
func main() {
defer profile.Start(profile.ProfilePath(".")).Stop()
fmt.Println("start")
for i := 0; i < 1000; i++ {
fib(30)
}
}
Step2: ビルドして、実行する
go build main.go
./main
2018/12/25 07:45:47 profile: cpu profiling enabled, cpu.pprof
start
2018/12/25 07:45:54 profile: cpu profiling disabled, cpu.pprof
Step3: 出力されたファイルを解析します。
go tool pprof -http=":8081" main cpu.pprof
http://localhost:8081/ui/
これでグラフ(flamegraph, graph)でどこにどれくらい時間・リソースがかかったかなどを見やすくすることもできます。
net/http/pprof
Step1: コードにプロファイラを埋め込む
import (
"fmt"
"log"
"net/http"
_ "net/http/pprof"
)
func fib(n int) int {
if n < 2 {
return n
}
return fib(n-1) + fib(n-2)
}
func main() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
fmt.Println("start")
for {
fib(30)
}
}
Step2: ビルドして、実行する
go build main.go
./main
start
2018/12/25 08:06:14 listen tcp 127.0.0.1:6060: bind: address already in use
Step3: プロファイルの解析
go tool pprof -http=":8081" http://localhost:6060/debug/pprof/profile
http://localhost:8081/ui/ で確認runtime/pprof
と同じくflamegraph, graphなど確認できます。
参考
https://www.youtube.com/watch?v=N3PWzBeLX2M
https://github.com/uber/go-torch
https://christina04.hatenablog.com/entry/golang-pprof-basic
https://flaviocopes.com/golang-profiling/
Goはあまり自信がないですが、できる限り調べました。
こうしたほうがいいよ!などありましたら教えてください