本文以leetcode的一題爲例來說解如何經過PProf來優化咱們的程序,題目以下:Longest Substring Without Repeating Charactersgit
func lengthOfNonRepeatingSubStr(s string) int {
lastOccurred := make(map[rune]int)
start := 0
maxLength := 0
for i, ch := range []rune(s) {
if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
start = lastI + 1
}
if i-start+1 > maxLength {
maxLength = i - start + 1
}
lastOccurred[ch] = i
}
return maxLength
}
複製代碼
性能檢測可知 200次, 花費時間 6970790 ns/op github
go test -bench . -cpuprofile cpu.out //首先生成cpuprofile文件
go tool pprof -http=:8080 ./啓動 PProf 可視化界面 分析cpu.out文件
複製代碼
經過訪問 http://localhost:8080/ui/ 能夠查看到以下頁面golang
能夠看到主要消耗時間在2大塊,一個是mapaccess,mapassign,還有一塊是decoderune。 decoderune主要是對UFT8字符的解碼,將字符串轉換成 []rune(s)
這個是不能避免的。因此主要去解決map的訪問和賦值問題,也就是代碼中的lastOccurred
bash
因爲map須要進行算hash 判重,分配空間等操做會致使操做慢下來,解決思路就是用空間換時間,經過slice來替換map.微信
修改後的代碼以下:函數
func lengthOfNonRepeatingSubStr2(s string) int {
lastOccurred := make([]int, 0xffff)
//賦給一個初始值
for i := range lastOccurred {
lastOccurred[i] = -1
}
start := 0
maxLength := 0
for i, ch := range []rune(s) {
if lastI := lastOccurred[ch]; lastI != -1 && lastI >= start {
start = lastI + 1
}
if i-start+1 > maxLength {
maxLength = i - start + 1
}
lastOccurred[ch] = i
}
return maxLength
}
複製代碼
性能檢測可知 500, 花費時間 2578859 ns/op。 相比以前的6970790 ns/op 已經又很大的優化了性能
經過pprof查看除了decoderune外還有一部分時間花費在makeslice上面,這是因爲每次調用函數都要makeslicke,能夠slice移到函數外面進行聲明。具體能夠本身操做下,而後查看下pprof圖上面的makeslice是否有消除。優化
PProf具使用可查看 Golang 大殺器之性能剖析 PProfui
本文亦在微信公衆號【小道資訊】發佈,歡迎掃碼關注! spa