ruk·si

Go
Optimization

Updated at 2015-10-04 08:36

Setup profiling harness with import _ "net/http/pprof".

package main

import (
    "fmt"
    "net/http"
    "time"
    _ "net/http/pprof"
)

func main() {
    http.HandleFunc("/", indexHandler)
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        panic(err)
    }
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Time is %s.", time.Now())
}

Or if you want to control the endpoint...

import "github.com/gorilla/mux"
import "net/http/pprof"
var handler *mux.Router
handler.PathPrefix("/debug/pprof/profile").HandlerFunc(pprof.Profile)
handler.PathPrefix("/debug/pprof/heap").HandlerFunc(pprof.Heap)

Profiling details are hosted at http://localhost:8080/debug/pprof/

Find What to Optimize

go build -o /tmp/go-app
/tmp/go-app
# Basic 30 second usage profiling.
curl http://localhost:8080/debug/pprof/profile > /tmp/go-app.profile
# make sure the app is doing the thing you want to profile
go tool pprof /tmp/go-app /tmp/go-app.profile
top
# Each node represents a procedure, showing which ones used the most CPU.
# Write help to get more info.
help
# Get heap usage on the machine.
curl http://localhost:8080/debug/pprof/heap > /tmp/go-app.heap
go tool pprof -h                                         # to list all options
go tool pprof -tree /tmp/go-app /tmp/go-app.heap         # print call tree graph
go tool pprof -alloc_objects /tmp/go-app /tmp/go-app.heap # allocated object cnt
go tool pprof -alloc_space /tmp/go-app /tmp/go-app.heap   # allocated memory sz
go tool pprof -lines /tmp/go-app /tmp/go-app.heap         # per line
go tool pprof -files /tmp/go-app /tmp/go-app.heap         # per file

top
# Showing in which function most of the allocations happen.
# Write help to get more commands.
help
list net.http

Find What is the Problem

go build -gcflags='-m' . 2>&1 | grep partitioner.go
# Prints compiler optimization decisions.

Always Benchmark Your Changes

# Run only specific benchmark, with memory info.
go test -v -bench . -run=_NONE_ -benchmem BenchmarkYourChange
# You seeing smaller numbers than before? Nice work!

Sources