最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go 庫性能分析工具pprof

 更新時(shí)間:2022年12月15日 10:50:06   作者:小馬別過河  
這篇文章主要為大家介紹了Go 庫性能分析工具pprof,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

場景

我們一般沒必要過度優(yōu)化 Go 程序性能。但是真正需要時(shí),Go 提供的 pprof 工具能幫我們快速定位到問題。比如,我們團(tuán)隊(duì)之前有一個(gè)服務(wù),在本地和測試環(huán)境沒問題,一到灰度環(huán)境,就報(bào) cpu 負(fù)載過高,后經(jīng)排查,發(fā)現(xiàn)某處代碼死循環(huán)了。我把代碼簡化成如下:

// 處理某些業(yè)務(wù),真實(shí)的代碼中這個(gè)死循環(huán)很隱蔽
func retrieveSomeThing() {
	for {}
}
// 處理其他的一些業(yè)務(wù),無意義,用于后續(xù)做例子
func doSomeThing() {
	do1()
	for i := 0; i < 200000000; i++ {}
	do2()
}
// 無意義
func do1() {
	for i := 0; i < 200000000; i++ {}
}
// 無意義
func do2() {
	for i := 0; i < 200000000; i++ {}
}
func main() {
	go retrieveSomeThing()
  go doSomeThing()
	// 阻塞一下
	time.Sleep(3 * time.Second)
}

解決問題前,先介紹下 pprof。

pprof

pprof 包會(huì)輸出運(yùn)行時(shí)的分析數(shù)據(jù)(profiling data),這些數(shù)據(jù)可以被 pprof 的可視化工具解析。Go 標(biāo)準(zhǔn)庫主要提供了兩個(gè)包:

  • runtime/pprof 通過寫入到文件的方式暴露 profile 數(shù)據(jù);
  • net/http/pprof 通過 http 服務(wù)暴露 profile 數(shù)據(jù),適用于守護(hù)進(jìn)程。

生成 profile 文件

CPU 性能分析

runtime/pprof 中,使用StartCPUProfile開啟 CPU 性能分析。退出程序前,需要調(diào)用StopCPUProfile把采樣數(shù)據(jù) flush 到輸出文件。

采樣的頻率默認(rèn)是 100 Hz(每秒 100 次)。

// 輸出到標(biāo)準(zhǔn)輸出,一般是指定文件
if err := pprof.StartCPUProfile(os.Stdout); err != nil {
    log.Fatal("could not start CPU profile: ", err)
}
defer pprof.StopCPUProfile()

內(nèi)存性能分析

調(diào)用 WriteHeapProfile 開啟內(nèi)存性能分析:

// 輸出到標(biāo)準(zhǔn)輸出,一般是指定文件
if err := pprof.WriteHeapProfile(os.Stdout); err != nil {
    log.Fatal("could not write memory profile: ", err)
}
}

分析 profile 文件 && 優(yōu)化代碼

以開篇的代碼為例,由于是 CPU 過載,我們可以在 main 函數(shù)開啟 CPU Profile:

// 通過參數(shù)指定 cpu profile 輸出的文件
var cpuprofile = flag.String("cpuprofile", "", "write cpu 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)
		}
		// 開啟 CPU 分析
		if err := pprof.StartCPUProfile(f); err != nil {
			log.Fatal("could not start CPU profile: ", err)
		}
		defer pprof.StopCPUProfile()
	}
	// 業(yè)務(wù)代碼
	go retrieveSomeThing()
  go doSomeThing()
	// 模擬阻塞
	time.Sleep(5 * time.Second)
}

我們執(zhí)行命令,輸出 profile 文件到 cpu.prof。

go run main.go -cpuprofile cpu.prof

go tool pprof

Go 提供性能解析工具:go tool pprof。我們使用 go tool 打開 profile 文件。

> go tool pprof cpu.prof 
Type: cpu
Time: Nov 16, 2022 at 1:40pm (CST)
Duration: 5.17s, Total samples = 4.54s (87.75%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) 

這是個(gè)交互式的界面,輸入help可以查看所有命令。

top 命令

我們使用 topN 命令,查看根據(jù) flat 從大到小排序的前 N 條數(shù)據(jù)。

(pprof) top10
Showing nodes accounting for 4650ms, 100% of 4650ms total
      flat  flat%   sum%        cum   cum%
    4220ms 90.75% 90.75%     4450ms 95.70%  main.retrieveSomeThing
     230ms  4.95% 95.70%      230ms  4.95%  runtime.asyncPreempt
      80ms  1.72% 97.42%      200ms  4.30%  main.doSomeThing
      70ms  1.51% 98.92%       70ms  1.51%  main.do2 (inline)
      50ms  1.08%   100%       50ms  1.08%  main.do1 (inline)

top 命令返回?cái)?shù)據(jù)有5個(gè)指標(biāo):

  • flat : 本函數(shù)占用的 CPU 時(shí)間,不包括調(diào)用函數(shù)的時(shí)間;
  • flat% : flat 占的百分比;
  • sum% : 前面 flat% 的總和;
  • cum : 累計(jì)時(shí)間,包括調(diào)用的函數(shù)的時(shí)間;
  • cum% : cum 的百分比。

main.doSomeThing(排第三的函數(shù))為例子,耗時(shí)為:

func doSomeThing() {                   // flat: 80ms  cum: 200ms
	do1()                                // 執(zhí)行時(shí)間 50ms
	for i := 0; i < 200000000; i++ {}    // 執(zhí)行時(shí)間 80ms
	do2()                                // 執(zhí)行時(shí)間 70ms
}

doSomeThing 的 flat 的值為:

for i := 0; i < 200000000; i++ {}的執(zhí)行時(shí)間(80ms),不包括do1和do2的時(shí)間。

doSomeThing 的 cum 的值為:

cum(200ms) = doSomething的flat(80ms) + do1的flat(50ms) + do2的flat(70ms)

ps: top 可以使用 -cum 參數(shù)來指定,根據(jù) cum 排序。

list 命令

明白了 top 的指標(biāo)的意思,我們關(guān)注到,排在 top1 的函數(shù)是 retrieveSomeThing??梢允褂?list 命令,查看 retrieveSomeThing 耗時(shí):

(pprof) list retrieveSomeThing
Total: 4.65s
ROUTINE ======================== main.retrieveSomeThing in /xxxx/pprof_note/pprof/main.go
     4.22s      4.45s (flat, cum) 95.70% of Total
      10ms       10ms      1:package main
         .          .      2:
         .          .      3:import (
         .          .      4:   "flag"
         .          .      5:   "log"
         .          .      6:   "os"
         .          .      7:   "runtime/pprof"
         .          .      8:   "time"
         .          .      9:)
         .          .     10:
         .          .     11:// 處理某些業(yè)務(wù),真實(shí)的代碼中這個(gè)死循環(huán)很隱蔽
         .          .     12:func retrieveSomeThing() {
     4.21s      4.44s     13:   for {
         .          .     14:   }
         .          .     15:}
         .          .     16:
         .          .     17:// 處理其他的一些業(yè)務(wù),無意義,用于后續(xù)做例子
         .          .     18:func doSomeThing() {

我們定位到13行需要優(yōu)化。

總結(jié)

pprof 還有很多玩法,包括其他的性能指標(biāo),go tool 的其他命令,profile 文件的可視化等。這個(gè)留給讀者自行擴(kuò)展閱讀。

本文主要參考了 Russ Cox 大神的文章:《Profiling Go Programs》 (go.dev/blog/pprof)… 文章為反駁 "Go性能不如其他語言"的觀點(diǎn),借助 pprof 大幅度優(yōu)化了程序的運(yùn)行時(shí)間和內(nèi)存。

以上就是Go 庫性能分析工具pprof的詳細(xì)內(nèi)容,更多關(guān)于Go pprof性能分析的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • GO語言異常處理機(jī)制panic和recover分析

    GO語言異常處理機(jī)制panic和recover分析

    這篇文章主要介紹了GO語言異常處理機(jī)制panic和recover,分析了捕獲運(yùn)行時(shí)發(fā)生錯(cuò)誤的方法,是非常實(shí)用的技巧,需要的朋友可以參考下
    2014-12-12
  • go語言打包的網(wǎng)頁wasm示例詳解

    go語言打包的網(wǎng)頁wasm示例詳解

    這篇文章主要為大家介紹了go打包網(wǎng)頁wasm示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2022-09-09
  • Go官方工具鏈用法詳解

    Go官方工具鏈用法詳解

    Go官方工具鏈工具要求所有的Go源代碼文件必須以.go后綴結(jié)尾。這里,我們假設(shè)一個(gè)最簡單的Go程序放在hello.go的文件中,下面通過示例代碼給大家介紹Go官方工具鏈用法簡介,需要的朋友可以參考下
    2021-10-10
  • 探索Go語言中的switch高級用法

    探索Go語言中的switch高級用法

    在Go語言中,switch語句除了常見的用法外,還有一種不常用但有趣的寫法,這種寫法中,switch后面不跟任何表達(dá)式,而每個(gè)case后面跟的是返回bool類型的函數(shù)調(diào)用表達(dá)式,這實(shí)際上是一個(gè)等價(jià)于switch true的用法,通過從上到下逐一比較case后的表達(dá)式是否為true來決定執(zhí)行哪個(gè)分支
    2024-10-10
  • Go語言學(xué)習(xí)之將mp4通過rtmp推送流媒體服務(wù)的實(shí)現(xiàn)方法

    Go語言學(xué)習(xí)之將mp4通過rtmp推送流媒體服務(wù)的實(shí)現(xiàn)方法

    對音視頻一直是小白,決定沉下心來,好好研究一下音視頻知識,下面這篇文章主要給大家介紹了關(guān)于Go語言學(xué)習(xí)之將mp4通過rtmp推送流媒體服務(wù)的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2022-12-12
  • Golang使用泛型對數(shù)組進(jìn)行去重的實(shí)現(xiàn)

    Golang使用泛型對數(shù)組進(jìn)行去重的實(shí)現(xiàn)

    本文主要介紹了Golang使用泛型對數(shù)組進(jìn)行去重的實(shí)現(xiàn),通過使用類型參數(shù)T和類型約束any,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • Go?1.21.0?新增結(jié)構(gòu)化日志記錄標(biāo)準(zhǔn)庫log/slog使用詳解

    Go?1.21.0?新增結(jié)構(gòu)化日志記錄標(biāo)準(zhǔn)庫log/slog使用詳解

    這篇文章主要為大家介紹了Go?1.21.0?新增結(jié)構(gòu)化日志記錄標(biāo)準(zhǔn)庫log/slog使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Golang精編49面試題匯總(選擇題)

    Golang精編49面試題匯總(選擇題)

    這篇文章主要介紹了Golang精編49面試題匯總(選擇題),本文章內(nèi)容詳細(xì),具有很好的參考價(jià)值,希望對大家有所幫助,需要的朋友可以參考下
    2023-01-01
  • Go標(biāo)準(zhǔn)庫http與fasthttp服務(wù)端性能對比場景分析

    Go標(biāo)準(zhǔn)庫http與fasthttp服務(wù)端性能對比場景分析

    這篇文章主要介紹了Go標(biāo)準(zhǔn)庫http與fasthttp服務(wù)端性能比較,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • 更高效的GoLevelDB:shardingdb實(shí)現(xiàn)分片和并發(fā)讀寫操作

    更高效的GoLevelDB:shardingdb實(shí)現(xiàn)分片和并發(fā)讀寫操作

    這篇文章主要介紹了更高效的GoLevelDB:shardingdb實(shí)現(xiàn)分片和并發(fā)讀寫操作的相關(guān)資料,需要的朋友可以參考下
    2023-09-09

最新評論

珲春市| 蒲城县| 灌云县| 汉中市| 启东市| 麦盖提县| 东至县| 兴宁市| 同德县| 丰镇市| 中阳县| 阿荣旗| 东丽区| 皋兰县| 高雄市| 革吉县| 乌苏市| 华容县| 固始县| 郓城县| 双城市| 曲松县| 鹤山市| 盘锦市| 台北县| 洪江市| 涿鹿县| 贵南县| 张家界市| 万源市| 黄大仙区| 娱乐| 庄浪县| 略阳县| 酉阳| 彝良县| 株洲县| 三亚市| 玉山县| 本溪市| 青阳县|