Open15
goのechoでpprofを扱ってみる
pprofとは
pprof is a tool for visualization and analysis of profiling data.
echo
High performance, minimalist Go web framework
pprofの基本的な使い方
documentのこのサンプルがわかりやすい
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal("could not create CPU profile: ", err)
}
defer f.Close() // error handling omitted for example
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("could not start CPU profile: ", err)
}
defer pprof.StopCPUProfile()
}
// ... rest of the program ...
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal("could not create memory profile: ", err)
}
defer f.Close() // error handling omitted for example
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("could not write memory profile: ", err)
}
}
}
他参考
http serverを起動する方
runtimeとhttpの2つがある
- runtime
- プログラムの個別部分をprofileできる
- http
- プログラム全体
- サーバーのプログラムなど
Echoでのpprofの基本的な使い方
ほぼ公式、のようなところから提供されてそう
シンプル
package main
import (
"net/http"
"github.com/labstack/echo/v4"
"github.com/labstack/echo-contrib/pprof"
)
func main() {
e := echo.New()
pprof.Register(e)
......
e.Logger.Fatal(e.Start(":1323"))
}
Goのnet/http/pprofパッケージは、DefaultServeMuxにデバッグ用のハンドラを登録するため、
DefaultServeMuxを使用していないechoでは別に処理が必要になる
documentで以下のようにimportするだけで動くのは、DefaultServeMuxにハンドラが登録されるから
import _ "net/http/pprof"
func init() {
http.HandleFunc("/debug/pprof/", Index)
http.HandleFunc("/debug/pprof/cmdline", Cmdline)
http.HandleFunc("/debug/pprof/profile", Profile)
http.HandleFunc("/debug/pprof/symbol", Symbol)
http.HandleFunc("/debug/pprof/trace", Trace)
}
echoはDefaultServeMux使ってないから、↓みたいに登録
計測してみる
package main
import (
"net/http"
"github.com/labstack/echo-contrib/pprof"
"github.com/labstack/echo/v4"
"golang.org/x/crypto/bcrypt"
)
func handler(c echo.Context) error {
for i := 0; i < 3; i++ {
bcrypt.GenerateFromPassword([]byte("PASSWORD"), bcrypt.DefaultCost)
}
arr := []int{}
for i := 0; i < 10000; i++ {
arr = append(arr, i)
}
return c.String(http.StatusOK, "ok")
}
func main() {
e := echo.New()
pprof.Register(e)
e.GET("/test", handler)
e.Start(":8080")
}
取れた
