golang profile用法

概要

profile就是定時(shí)采樣抹剩,收集cpu撑帖,內(nèi)存等信息,進(jìn)而給出性能優(yōu)化指導(dǎo)澳眷,golang 官方提供了golang自己的性能分析工具的用法胡嘿,也給出了指導(dǎo),官方的介紹

環(huán)境

golang環(huán)境境蔼, graphviz

生成profile方法

golang目前提供了3中profile灶平,分別是 cpu profile, memery profile, blocking profile, 對(duì)于如何生成這些profile有兩種辦法伺通,一種是使用 net/http/pprof 包,一種是需要自己手寫代碼逢享,下面分別介紹一下

1. net/http/pprof 方法

這種方法是非常非常簡(jiǎn)單的罐监,只需要引入 net/http/pprof 包就可以了,網(wǎng)頁上可以查看

package main

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

func main() {
    go func() {
        for {
            fmt.Println("hello world")
        }
    }()
    log.Fatal(http.ListenAndServe("0.0.0.0:8080", nil))
}

http://127.0.0.1:8080/debug/pprof 查看整體信息
http://127.0.0.1:8080/debug/pprof/profile 可以將cpu profile下載下來觀察分析

從terminal進(jìn)入profile瞒爬,進(jìn)行細(xì)致分析
go tool pprof http://localhost:6060/debug/pprof/profile
go tool pprof http://localhost:6060/debug/pprof/heap
go tool pprof http://localhost:6060/debug/pprof/block

  1. 寫代碼的方法
func main() {
    cpuf, err := os.Create("cpu_profile")
    if err != nil {
        log.Fatal(err)
    }
    pprof.StartCPUProfile(cpuf)
    defer pprof.StopCPUProfile()

    ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
    test(ctx)

    time.Sleep(time.Second * 3)
    memf, err := os.Create("mem_profile")
    if err != nil {
        log.Fatal("could not create memory profile: ", err)
    }
    if err := pprof.WriteHeapProfile(memf); err != nil {
        log.Fatal("could not write memory profile: ", err)
    }
    memf.Close()
}

func test(c context.Context) {
    i := 0
    j := 0
    go func() {
        m := map[int]int{}
        for {
            i++
            m[i] = i
        }
    }()
    go func() {
        m := map[int]int{}
        for {
            j++
            m[i] = i
        }
    }()
    select {
    case <-c.Done():
        fmt.Println("done, i", i, "j", j)
        return
    }
}

會(huì)生成兩個(gè)profile弓柱,一個(gè)是cpu的,一個(gè)是內(nèi)存的侧但。進(jìn)入proflie 方法

go tool pprof main profile
main 代表的是二進(jìn)制文件矢空,也就是編譯出來的可執(zhí)行文件
profile 就是上文中生成的profile,可以是cpu_profile, 也可以是mem_profile

對(duì)于cpu_profile 來說禀横,代碼開始的時(shí)候就可以開始統(tǒng)計(jì)了
mem_profile 部分代碼如果寫在代碼開始的位置是統(tǒng)計(jì)不出來的屁药,需要找到一個(gè)比較好的位置

如何分析 profile

1.示例代碼如下
package main

import (
    "flag"
    "fmt"
    "log"
    "math/rand"
    "os"
    "runtime/pprof"
    "sort"
    "time"
)

var num = 100000000
var findNum = 10000000

var t = flag.String("t", "map", "use map")

func main() {
    cpuf, err := os.Create("cpu_profile")
    if err != nil {
        log.Fatal(err)
    }
    pprof.StartCPUProfile(cpuf)
    defer pprof.StopCPUProfile()

    flag.Parse()
    if *t == "map" {
        fmt.Println("map")
        findMapMax()
    } else {
        fmt.Println("slice")
        findSliceMax()
    }
}

func findMapMax() {
    m := map[int]int{}
    for i := 0; i < num; i++ {
        m[i] = i
    }

    for i := 0; i < findNum; i++ {
        toFind := rand.Int31n(int32(num))
        _ = m[int(toFind)]
    }
}

func findSliceMax() {
    m := make([]int, num)
    for i := 0; i < num; i++ {
        m[i] = i
    }

    for i := 0; i < findNum; i++ {
        toFind := rand.Int31n(int32(num))
        v := sort.SearchInts(m, int(toFind))
        fmt.Println(v)
    }
}

代碼很簡(jiǎn)單,主要是為了介紹如何分析profile柏锄,達(dá)到效果即可酿箭,不要在意細(xì)節(jié)。
這段代碼就是分別用 map, slice 兩種數(shù)據(jù)結(jié)構(gòu), 先生成 num 個(gè)元素趾娃,在從map, slice 中 隨機(jī)找到 findNum 個(gè)元素缭嫡, 選用map 還是 slice 可以通過 -t 來指定,本demo采用 非 net/http/pprof 方式

2.準(zhǔn)備工作

需要生成 profile 文件 和 二進(jìn)制文件
生成二進(jìn)制文件: go build main.go (執(zhí)行命令后會(huì)生成 main 二進(jìn)制文件)
生成 profile: ./main (不指定-t 抬闷,默認(rèn)使用map數(shù)據(jù)結(jié)構(gòu),會(huì)生成 cpu_profile, 這個(gè)文件就是我們要分析的profile)

3.分析profile
  • 現(xiàn)在準(zhǔn)備工作做好了妇蛀,我們目前生成了 main 二進(jìn)制可執(zhí)行文件,cpu_profile 性能分析需要的profile, 接下來我們要正式進(jìn)入profile進(jìn)行分析了
  • go tool pprof main cpu_profile 執(zhí)行這個(gè)命令就進(jìn)入了profile 文件了笤成,這時(shí)候我們已經(jīng)可以開始分析代碼了
  • 輸入help评架,可以查看都支持哪些操作,有很多命令可以根據(jù)需要進(jìn)行選擇疹启,我們只介紹4個(gè)我自己比較喜歡用的命令 web, top, peek, list
    *web----- 在profile輸入 web, 會(huì)生成網(wǎng)頁版的調(diào)用分析圖(需要安裝 graphviz)如下圖:
    web

    輸入web命令后古程,會(huì)自動(dòng)打開瀏覽器出現(xiàn)如下內(nèi)容:
    web2

這樣就可以看到每個(gè)步驟占用多少時(shí)間了蔼卡,可以對(duì)性能進(jìn)行大致的分析喊崖,但是很多時(shí)候可能出現(xiàn)的并不是我們關(guān)心的,比如這個(gè)demo中看到的都是不認(rèn)識(shí)的函數(shù)(其實(shí)都是map的runtime操作)

  • top----- 在profile 中輸入top雇逞,會(huì)列出來幾個(gè)最耗時(shí)的操作


    web2

因?yàn)樾阅芙y(tǒng)計(jì)都是采樣操作荤懂,所以不是每次統(tǒng)計(jì)出來的都一樣, 最重要的是經(jīng)常統(tǒng)計(jì)出來的都是底層操作塘砸,并不是我們關(guān)心的节仿,而且也不是每個(gè)人都能看得懂,我們更需要一種直觀的辦法掉蔬,很直觀的能把自己寫的代碼耗時(shí)都看出來廊宪,下面就介紹一種我個(gè)人覺得非常好的方法矾瘾。

  • peek,list 妙用
    peek 是用來查詢 函數(shù)名字的(這個(gè)名字是list需要使用的名字,并不完全等于函數(shù)名)
    list 是用來將函數(shù)時(shí)間消耗列出來的
    1)list main.main


    web2
  1. peek findMapMax (因?yàn)楦鶕?jù)1可以看出來消耗都在 findMapMax)


    web2

    3)list main.findMapMax (根據(jù)2可以看出來名字是 main.findMapMax)


    web2

妙用 peek list指令可以很直觀的看出來箭启,我們的代碼問題在 m[i] = i, 這就說明了就是map的寫操作耗費(fèi)了38.75s, 而44行的讀操作只用了2.35s, 針對(duì)這個(gè)demo壕翩,我們要優(yōu)化的就是 m[i] = i ,因?yàn)檫@句操作已經(jīng)語言級(jí)別的傅寡,我們是沒有能力對(duì)他進(jìn)行優(yōu)化的放妈,所以這時(shí)候如果需求只能用map,那么這個(gè)程序幾乎沒有優(yōu)化空間了荐操,如果需求可以使用其他的數(shù)據(jù)結(jié)構(gòu)芜抒,那我們肯定會(huì)把map修改為slice,眾所周知 map 每次存一個(gè)函數(shù)都要進(jìn)行hash計(jì)算托启,而且存的多了到達(dá)一定的數(shù)量宅倒,還要重新對(duì)map進(jìn)行重新分配空間的操作,所以肯定是耗時(shí)的屯耸。

總結(jié)

  1. go run main.go -t=slice 會(huì)使用slice的數(shù)據(jù)結(jié)構(gòu)唉堪,同學(xué)們可以自行按照文章的方法進(jìn)行分析一下,檢驗(yàn)一下自己掌握的如何肩民。
  2. 在profile中執(zhí)行help命令唠亚,會(huì)列出所有的命令,有興趣可以去研究
  3. memory 也是同樣的分析方法持痰,demo 中 mem_profile 生成的位置可能需要調(diào)整灶搜,我沒有進(jìn)行驗(yàn)證,降低memory 使用也會(huì)大幅提升性能工窍。
  4. 還有一種 blocking profile 在手寫方式中沒有給出割卖,有興趣的可以自己google一下

過早的優(yōu)化是萬惡之源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市患雏,隨后出現(xiàn)的幾起案子鹏溯,更是在濱河造成了極大的恐慌,老刑警劉巖淹仑,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丙挽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡匀借,警方通過查閱死者的電腦和手機(jī)颜阐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吓肋,“玉大人凳怨,你說我怎么就攤上這事。” “怎么了肤舞?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵紫新,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我李剖,道長(zhǎng)弊琴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任杖爽,我火速辦了婚禮敲董,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘慰安。我一直安慰自己尊浪,他們只是感情好票摇,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布尼荆。 她就那樣靜靜地躺著坝咐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪撒桨。 梳的紋絲不亂的頭發(fā)上查刻,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音凤类,去河邊找鬼穗泵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谜疤,可吹牛的內(nèi)容都是我干的佃延。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼夷磕,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼履肃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起坐桩,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤尺棋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后绵跷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膘螟,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年抖坪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了萍鲸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡擦俐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出握侧,到底是詐尸還是另有隱情蚯瞧,我是刑警寧澤嘿期,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站埋合,受9級(jí)特大地震影響备徐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜甚颂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一蜜猾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧振诬,春花似錦蹭睡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至辫呻,卻和暖如春清钥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背放闺。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工祟昭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怖侦。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓从橘,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親础钠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子恰力,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)自:http://lihaoquan.me/2017/1/1/Profiling-and-Optimizing-...
    鯨息_Leon閱讀 7,685評(píng)論 0 11
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)旗吁,斷路器踩萎,智...
    卡卡羅2017閱讀 134,628評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,737評(píng)論 25 707
  • 先聲明一下本人是90后平面設(shè)計(jì)師一枚,不是做產(chǎn)品的很钓,主要是第一次寫文章香府,語言的表述或用詞有可能不準(zhǔn)確或比較膚...
    張小謙_up閱讀 1,067評(píng)論 2 5
  • 37,42,31,32,122,123,炮,工防码倦,特作企孩,勤支,空突121袁稽,防空
    勇于思索閱讀 142評(píng)論 0 0