美文网首页
12 - 性能分析工具

12 - 性能分析工具

作者: 天命_风流 | 来源:发表于2020-07-15 09:11 被阅读0次

    准备工作

    • 在对 go 的性能进行分析之前,我们需要做一些准备工作,具体如下


      image.png

    在代码中嵌入性能分析的 API

    image.png
    • 你可以分析程序在执行时的 CPU
    • 你可以分析内存
    • 还有很多内容,你都可以选择监控
    package main
    
    import (
        "log"
        "math/rand"
        "os"
        "runtime/pprof"
        "time"
    )
    
    const (
        col = 10000
        row = 10000
    )
    
    func fillMatrix(m *[row][col]int) {
        s := rand.New(rand.NewSource(time.Now().UnixNano()))
    
        for i := 0; i < row; i++ {
            for j := 0; j < col; j++ {
                m[i][j] = s.Intn(100000)
            }
        }
    }
    
    func calculate(m *[row][col]int) {
        for i := 0; i < row; i++ {
            tmp := 0
            for j := 0; j < col; j++ {
                tmp += m[i][j]
            }
        }
    }
    
    func main() {
        //创建输出文件
        f, err := os.Create("cpu.prof")  // 创建一个文件句柄,这个会收集程序在执行的时候的 CPU 状态
        if err != nil {
            log.Fatal("could not create CPU profile: ", err)
        }
    
        // 获取系统信息
        if err := pprof.StartCPUProfile(f); err != nil { // 监控开始
            log.Fatal("could not start CPU profile: ", err)
        }
        defer pprof.StopCPUProfile()  // 在程序结束的时候结束监控
    
        // 主逻辑区,进行一些简单的代码运算
        x := [row][col]int{}
        fillMatrix(&x)
        calculate(&x)
    
        f1, err := os.Create("mem.prof")  // 做一个句柄,用于收集程序的内存状态
        if err != nil {
            log.Fatal("could not create memory profile: ", err)
        }
        //runtime.GC()                                       // GC,获取最新的数据信息
        if err := pprof.WriteHeapProfile(f1); err != nil {  // 写入内存信息
            log.Fatal("could not write memory profile: ", err)
        }
        f1.Close()  // 关闭内存监控
    
        f2, err := os.Create("goroutine.prof")  // 打开一个句柄,用于收集其他信息
        if err != nil {
            log.Fatal("could not create groutine profile: ", err)
        }
    
        if gProf := pprof.Lookup("goroutine"); gProf == nil {  // 使用 lookup 可以选择你想要监控的类型,这里选择的是协程
            log.Fatal("could not write groutine profile: ")
        } else {
            gProf.WriteTo(f2, 0)
        }
        f2.Close()
    
    }
    
    • 如果你想了解其他可以监控的内容,可以在下面寻找
    image.png
    • go build prof.go 创建二进制文件
    • 执行这个二进制文件,在目录中会出现相关的分析文件
    • 使用 go tool pprof pro xxx.prof ,可以进入相关文件的控制台
    • 在控制台中,使用 top 、list 等命令可以查看详细内容
    • 使用 svg 可以生成图,你可以用浏览器打开

    使用火炬图 go-torch

    • 在目录下使用 go-torch xxx.prof ,可以生成火炬图

    使用 http 持续监控

    image.png
    • 使用斐波那契数列的代码作为例子
    package main
    
    import (
        "fmt"
        "log"
        "net/http"
        _ "net/http/pprof"
    )
    
    func GetFibonacciSerie(n int) []int {
        ret := make([]int, 2, n)
        ret[0] = 1
        ret[1] = 1
        for i := 2; i < n; i++ {
            ret = append(ret, ret[i-2]+ret[i-1])
        }
        return ret
    }
    
    func index(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Welcome!"))
    }
    
    func createFBS(w http.ResponseWriter, r *http.Request) {
        var fbs []int
        for i := 0; i < 1000000; i++ {
            fbs = GetFibonacciSerie(50)
        }
        w.Write([]byte(fmt.Sprintf("%v", fbs)))
    
    }
    
    func main() {
        http.HandleFunc("/", index)
        http.HandleFunc("/fb", createFBS)
        log.Fatal(http.ListenAndServe(":8081", nil))
    }
    

    相关文章

      网友评论

          本文标题:12 - 性能分析工具

          本文链接:https://www.haomeiwen.com/subject/ghpscktx.html