graphviz 安装及golang profile简单用例

cli1871 · · 1294 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

安装

brew install graphviz

Check安装

ccli@ccli-mac:perftest$ dot -h

Error: dot: option -h unrecognized

Usage: dot [-Vv?] [-(GNE)name=val] [-(KTlso)<val>] <dot files>

(additional options for neato)    [-x] [-n]

(additional options for fdp)      [-L(gO)] [-L(nUCT)]

(additional options for memtest)  [-m]

(additional options for config)  [-cv]

 -V          - Print version and exit

...

dot已经安装了,并且add into 你的PATH环境变量中

图形生成

编辑文件my1st.dot

digraph d { 

 A [label="Hello"]

 B [label="World"]

 C [label="Everyone"]

 A -> { B C } 

}

ccli@ccli-mac:perftest$ dot -T png -O my1st.dot

ccli@ccli-mac:perftest$ ls

my1st.dot my1st.dot.png

查看png


my1st.dot.png


CPU Profiling

set GOPATH

export GOPATH=/Users/ccli/tool/perftest

Step #1: download github.com/pkg/profile

go get github.com/pkg/profile

Step #2: add profiling into the main() function of your command, Eg:

package main

import (

        "io"

        "io/ioutil"

        "log"

        "os"

        "path/filepath"

        "text/template"

        "time"

        "github.com/pkg/profile"

)

// templateFile defines the contents of a template to be stored in a file, for testing.

type templateFile struct {

        name    string

        contentsstring

}

func createTestDir(files []templateFile) string {

        dir, err := ioutil.TempDir("", "template")

        if err != nil {

                log.Fatal(err)

        }

        for _, file := range files {

                f, err := os.Create(filepath.Join(dir, file.name))

                if err != nil {

                        log.Fatal(err)

                }

                defer f.Close()

                _, err = io.WriteString(f, file.contents)

                if err != nil {

                        log.Fatal(err)

                }

        }

        return dir

}

func testSleep() {

        time.Sleep(3 * time.Second)

}

func main() {

        defer profile.Start().Stop()

        // Here we create a temporary directory and populate it with our sample

        // template definition files; usually the template files would already

        // exist in some location known to the program.

        dir := createTestDir([]templateFile{

                // T0.tmpl is a plain template file that just invokes T1.

                {"T0.tmpl", `T0 invokes T1: ({{template "T1"}})`},

                // T1.tmpl defines a template, T1 that invokes T2.

                {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},

                // T2.tmpl defines a template T2.

                {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},

        })

        // Clean up after the test; another quirk of running as an example.

        defer os.RemoveAll(dir)

        // pattern is the glob pattern used to find all the template files.

        pattern := filepath.Join(dir,"*.tmpl")

        // Here starts the example proper.

        // T0.tmpl is the first name matched, so it becomes the starting template,

        // the value returned by ParseGlob.

        tmpl := template.Must(template.ParseGlob(pattern))

        testSleep()

        err := tmpl.Execute(os.Stdout,nil)

        if err != nil {

                log.Fatalf("template execution: %s", err)

        }

}

Step #3: build and run your program

This will generate a *.pprof file in a temp folder, and tell you where it’s located (will be needed later)

ccli@ccli-mac:src$ go build -o text_template text_template.go 

ccli@ccli-mac:src$ ./text_template 

2019/05/16 15:32:01 profile: cpu profiling enabled, /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile962071122/cpu.pprof

T0 invokes T1: (T1 invokes T2: (This is T2))2019/05/16 15:32:04 profile: cpu profiling disabled, /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile962071122/cpu.pprof

Step #4: run go tool pprof

Pass your binary location, and the location of the cpu.pprof file as returned when running your program.

You can generate the analysis in various formats. The PDF one is pretty amazing:

go tool pprof --pdf ./text_template /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile962071122/cpu.pprof > text_template.pdf


text_template.pdf

这里仅仅是为了举例说明,因函数调用简单,没有call diagram,方法步骤是正确的。

You can generate other kind of visualizations as well, e.g. txt:

go tool pprof --text ./text_template /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile962071122/cpu.pprof > text_template.txt


Memory Profiling

Memory profiling is essentially the same as CPU profiling, but instead of using the default configuration for profile.Start(), we pass a profile.MemProfile flag:

defer profile.Start(profile.MemProfile).Stop()

thus the code becomes

package main

import (

        //...

        "github.com/pkg/profile"

)

func main() {

        // Memory profiling

        defer profile.Start(profile.MemProfile).Stop()

        //...

}

and when running the program, it will generate a mem.pprof file instead of cpu.pprof.

ccli@ccli-mac:src$ go build -o text_template text_template.go 

ccli@ccli-mac:src$ ./text_template 

2019/05/16 15:48:23 profile: memory profiling enabled (rate 4096), /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile006546943/mem.pprof

T0 invokes T1: (T1 invokes T2: (This is T2))2019/05/16 15:48:26 profile: memory profiling disabled, /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile006546943/mem.pprof

ccli@ccli-mac:src$ go tool pprof --pdf ./text_template /var/folders/2t/3jfn39hx62s6sn97r4m2rp2rb8f5tm/T/profile006546943/mem.pprof > text_template.pdf

ccli@ccli-mac:src$ 

Diagram screenshot:


Read more about profiling Go apps

This is just a start. Read more at:

https://blog.golang.org/profiling-go-programs

Lower level: https://golang.org/pkg/runtime/pprof/

More options for advanced usage of github.com/pkg/profilehttp://godoc.org/github.com/pkg/profile


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:cli1871

查看原文:graphviz 安装及golang profile简单用例

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

1294 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传