欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang?pprof性能測試與分析講解

 更新時(shí)間:2023年04月04日 11:37:02   作者:qq_42170897  
剛開始接觸go就遇到了一個(gè)內(nèi)存問題,在進(jìn)行內(nèi)存分析的時(shí)候發(fā)現(xiàn)了一下比較好的工具,在此留下記錄,下面這篇文章主要給大家介紹了關(guān)于go性能分析工具pprof的性能測試,需要的朋友可以參考下

一、性能分析類型

1.CPU性能分析

CPU性能分析是最常見的性能分析類型。啟動CPU分析時(shí),運(yùn)行時(shí)每隔10ms中斷一次,采集正在運(yùn)行協(xié)程的堆棧信息。

程序運(yùn)行結(jié)束后,可以根據(jù)收集的數(shù)據(jù),找到最熱代碼路徑。

一個(gè)函數(shù)在分析階段出現(xiàn)的次數(shù)越多,則該函數(shù)的代碼路徑(code path)花費(fèi)的時(shí)間占總運(yùn)行時(shí)間的比重越大。

2.內(nèi)存性能分析

內(nèi)存性能分析記錄堆內(nèi)存分配信息,忽略棧內(nèi)存的分配。

內(nèi)存分析啟動時(shí),默認(rèn)每1000次采樣1次,這個(gè)比例是可以調(diào)整的。因?yàn)閮?nèi)存性能分析是基于采樣的,因此基于內(nèi)存分析數(shù)據(jù)來判斷程序所有的內(nèi)存使用情況是很困難的。

3.阻塞性能分析

阻塞性能分析是go特點(diǎn)的。

阻塞性能分析用來記錄一個(gè)協(xié)程用來等待共享資源所花費(fèi)的時(shí)間,這用來判斷程序并發(fā)瓶頸是很有用。阻塞的場景包括:

  • 在沒有緩沖的信道上發(fā)送或接受數(shù)據(jù)。
  • 在空的信道上接受數(shù)據(jù)或在滿的信道上發(fā)送數(shù)據(jù)。
  • 嘗試獲取一個(gè)已被其他協(xié)程占用的排他鎖。

一般情況下,當(dāng)所有的 CPU 和內(nèi)存瓶頸解決后,才會考慮這一類分析。

二、cpu性能分析

1.生成pporf

go 性能分析接口位于runtime/pprof 中:

測試代碼:生成5組數(shù)據(jù),進(jìn)行冒泡排序:

main.go

// main.go
package main
import (
	"math/rand"
	"time"
)
func generate(n int) []int {
	rand.Seed(time.Now().UnixNano())
	nums := make([]int, 0)
	for i := 0; i < n; i++ {
		nums = append(nums, rand.Int())
	}
	return nums
}
func bubbleSort(nums []int) {
	for i := 0; i < len(nums); i++ {
		for j := 1; j < len(nums)-i; j++ {
			if nums[j] < nums[j-1] {
				nums[j], nums[j-1] = nums[j-1], nums[j]
			}
		}
	}
}
func main() {
	n := 10
	for i := 0; i < 5; i++ {
		nums := generate(n)
		bubbleSort(nums)
		n *= 10
	}
}

想要度量這段代碼的性能,只需要在main函數(shù)最前加兩行代碼:

main()

import (
	"math/rand"
	"os"
	"runtime/pprof"
	"time"
)
func main() {
	pprof.StartCPUProfile(os.Stdout)
	defer pprof.StopCPUProfile()
	n := 10
	for i := 0; i < 5; i++ {
		nums := generate(n)
		bubbleSort(nums)
		n *= 10
	}
}

go run main.go > cpu.pprof

當(dāng)然也可以將輸出直接導(dǎo)入到文件中:

2.分析數(shù)據(jù)

此時(shí)得到cpu.pprof 文件:

go tool pprof -http=:9999 cpu.pprof 如果提升Graphviz沒有安裝: apt installgraphviz (ubuntu)

訪問localhost:9999 得到:

除了在網(wǎng)頁中查看外,還可以使用交互式命令進(jìn)行查看:

go tool pprof cpu.pprof

使用top 查看到 bubbleSort函數(shù)占用cpu最多。

還可以使用top --cum,按照cum(累計(jì)消耗)排序:

使用help 查看幫助:

三、內(nèi)存性能分析

下面為一段字符串拼接代碼,我們對它進(jìn)行內(nèi)存分析:

package main
import (
	"math/rand"
	"github.com/pkg/profile"
)
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func randomString(n int) string {
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	return string(b)
}
func concat(n int) string {
	s := ""
	for i := 0; i < n; i++ {
		s += randomString(n)
	}
	return s
}
func main() {
	concat(100)
}

我們使用另外一個(gè)性能分析庫"github.com/pkg/profile" 它內(nèi)部封裝了 runtime/pprof 接口,使用起來更加簡單。

cpu性能分析:

defer profile.Start().Stop()

內(nèi)存性能分析:

defer profile.Start(profile.MemProfile, profile.MemProfileRate(1)).Stop()

profile包會自動在/tmp目錄下生成profile文件

go tool pprof -http=:9999 /tmp/profile575547387/mem.pprof

可以看見concat 消耗了 524 KB, 而randomString消耗了 21KB,為什么相差這么大呢?

因?yàn)間o中的字符串不可修改,使用+ 連接字符串會導(dǎo)致重新生成新的字符串,將 + 兩邊的子字符串拷貝到新的字符串去。那這種設(shè)計(jì)多次字符串拼接的場景該如何優(yōu)化呢?使用strings.Builder

優(yōu)化后的代碼:

package main
import (
	"math/rand"
	"strings"
	"github.com/pkg/profile"
)
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func randomString(n int) string {
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	return string(b)
}
func concat(n int) string {
	sb := new(strings.Builder)
	for i := 0; i < n; i++ {
		sb.WriteString(randomString(n))
	}
	return sb.String()
}
func main() {
	defer profile.Start(profile.MemProfile, profile.MemProfileRate(1)).Stop()
	concat(100)
}

優(yōu)化后可以看到concat 函數(shù)使用了71KB 內(nèi)存,randomString函數(shù)使用了 21kb 內(nèi)存。

四、benchmark 生成 profile

使用benchmark 進(jìn)行基準(zhǔn)測試時(shí),除了直接查看結(jié)果,還可以生成profile

testing支持cpu、mem、block

  • -cpuprofile=$FILE
  • -memprofile=$FILE, -memprofilerate=N 調(diào)整記錄速率為原來的 1/N。
  • -blockprofile=$FILE

fib_test.go

package fib
import "testing"
func fib(n int) int {
	if n == 0 || n == 1 {
		return n
	}
	return fib(n-2) + fib(n-1)
}
func BenchmarkFib(b *testing.B) {
	for n := 0; n < b.N; n++ {
		fib(30) // run fib(30) b.N times
	}
}

go test -bench=. test/bench/fib -cpuprofile=cpu.pprof

go tool pprof -test cpu.pprof

go tool pprof 支持多種輸出格式:

go tool pprof

到此這篇關(guān)于Golang pprof性能測試與分析講解的文章就介紹到這了,更多相關(guān)Go pprof性能測試內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • GO 使用Webhook 實(shí)現(xiàn)github 自動化部署的方法

    GO 使用Webhook 實(shí)現(xiàn)github 自動化部署的方法

    這篇文章主要介紹了GO 使用Webhook 實(shí)現(xiàn)github 自動化部署的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Go 實(shí)現(xiàn)基于Token 的登錄流程深度分析

    Go 實(shí)現(xiàn)基于Token 的登錄流程深度分析

    Token 認(rèn)證機(jī)制的核心思想是,服務(wù)端在用戶登錄時(shí)生成一個(gè) Token,客戶端在后續(xù)的請求中攜帶這個(gè) Token,服務(wù)端通過驗(yàn)證 Token 的有效性來確認(rèn)用戶的身份,本文將帶你深入探索基于 Token 的登錄流程,這是一種更為靈活且適用于現(xiàn)代應(yīng)用架構(gòu)的認(rèn)證方式
    2024-03-03
  • Golang中struct{}和struct{}{}的區(qū)別解析

    Golang中struct{}和struct{}{}的區(qū)別解析

    這篇文章主要介紹了Golang中struct{}和struct{}{}的區(qū)別,通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Go 修改map slice array元素值操作

    Go 修改map slice array元素值操作

    這篇文章主要介紹了Go 修改map slice array元素值操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言遞歸函數(shù)的具體實(shí)現(xiàn)

    Go語言遞歸函數(shù)的具體實(shí)現(xiàn)

    本文主要介紹了Go語言遞歸函數(shù)的具體實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • go日志系統(tǒng)logrus顯示文件和行號的操作

    go日志系統(tǒng)logrus顯示文件和行號的操作

    這篇文章主要介紹了go日志系統(tǒng)logrus顯示文件和行號的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Go語言實(shí)現(xiàn)聊天小工具的示例代碼

    Go語言實(shí)現(xiàn)聊天小工具的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Go語言實(shí)現(xiàn)聊天小工具,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 一文教你如何封裝安全的go

    一文教你如何封裝安全的go

    這篇文章主要給大家介紹了關(guān)于如何封裝安全go的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-02-02
  • goframe重寫FastAdmin后端實(shí)現(xiàn)實(shí)例詳解

    goframe重寫FastAdmin后端實(shí)現(xiàn)實(shí)例詳解

    這篇文章主要為大家介紹了goframe重寫FastAdmin后端實(shí)現(xiàn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • GoLang unsafe包詳細(xì)講解

    GoLang unsafe包詳細(xì)講解

    從golang的定義來看,unsafe 是類型安全的操作。顧名思義,它應(yīng)該非常謹(jǐn)慎地使用; unsafe可能很危險(xiǎn),但也可能非常有用。例如,當(dāng)使用系統(tǒng)調(diào)用和Go結(jié)構(gòu)必須具有與C結(jié)構(gòu)相同的內(nèi)存布局時(shí),您可能別無選擇,只能使用unsafe
    2022-10-10

最新評論