Go学习:pprof性能调优

编程入门 行业动态 更新时间:2024-10-12 14:23:48

Go学习:pprof<a href=https://www.elefans.com/category/jswz/34/1771266.html style=性能调优"/>

Go学习:pprof性能调优

调优前

代码

package main/**
无重复字符的最长字串;支持中文
*/
func lengthOfNonRepratingSubStr(s string) int {lastOccurred := make(map[rune]int)start := 0maxLen := 0for i, ch := range []rune(s) {if lastIndex, ok := lastOccurred[ch]; ok && lastIndex >= start {start = lastIndex + 1}if i-start+1 > maxLen {maxLen = i - start + 1}lastOccurred[ch] = i}return maxLen
}

性能测试

func BenchmarkSubStr(b *testing.B) {param := "黑化肥挥发发灰会花飞灰化肥挥发发黑会飞花"for i := 0; i < 13; i++ {param = param + param}b.Logf("len(param) = %d",len(param))for i := 0; i < b.N; i++ {val := lengthOfNonRepratingSubStr(param)ans := 8if val != ans {b.Errorf("lengtyum install graphvizhOfNonRepratingSubStr(%s); 期望值:%d; 实际值: %d", param, ans, val)}}
}


没有进行调优时,进行性能测试12920060 ns/op;不算特别慢;但是还可以更快!

Graphviz

使用Graphviz和pprof命令分析代码现在的问题;然后有针对性的去优化代码

Graphviz介绍

      Graphviz是贝尔实验室开发的一个开源的工具包,它使用一个特定的DSL(领域特定语言):dot作为脚本语言,然后使用布局引擎来解析此脚本,并完成自动布局.

Graphviz安装

      Graphviz本身是一个绘图工具软件,下载点击地址.如果你是linux,可以用api-get或者yum的方法安装.如果是windows,就在官网下载msi文件安装;无论是linux还是windows,装完后都要设置环境变量.

调优

分析代码


  • 使用到的命令
go test -bench .
go test -bench . -cpuprofile cpu.out
go tool pprof cpu.out
web

优化思路

  • 我们通过命令+Graphviz生成出一张图;这张图的方框有大有小;线有粗有细,方框越大消耗的时间越长,线越粗消耗的时间越长
  • 通过对图片的分析
    • mapaccess2_fast32 0.38s (18.18%) of 0.62s (29.67%)
    • mapassign_fast32 0.39s (18.66%) of 0.57s (27.27%)
    • stringtoslicerune 0.20s (9.57%) of 0.49s (23.44%)
  • 主要是map和把参数转成[]rune消耗比较大;但是我们有utf8字符串传进来,解码是必不可少的,就只能在map上进行优化

优化代码

使用数组代替map;用空间换时间.map里面每个rune塞进去,它要算哈希;要判重;要分配空间;这一系列操作都太慢了;我们使用数组一开始就把空间分配好;使用空间来换时间

func lengthOfNonRepratingSubStr(s string) int {lastOccurred := make([]int, 0xffff)for i := range lastOccurred {lastOccurred[i] = -1}start := 0maxLen := 0for i, ch := range []rune(s) {if lastIndex := lastOccurred[ch]; lastIndex != -1 && lastIndex >= start {start = lastIndex + 1}if i-start+1 > maxLen {maxLen = i - start + 1}lastOccurred[ch] = i}return maxLen
}

初步优化,进行性能测试4562497 ns/op;性能提高的非常明显,肉眼可见

再次进行分析


通过对图片进行分析

  • stringtoslicerune 0.35s (16.91%) of 1.17s (56.52%);解码必不可少
  • asyncPreempt 0.02s (0.97%); asyncPreempt异步无需优化
  • makeslice 0 of 0.11s (5.31%); 创建数组花费的时间还可以继续优化;

优化代码

我们把创建数组的动作提到函数外面,把创建数组的动作减少到一次

var lastOccurred = make([]int, 0xffff)func lengthOfNonRepratingSubStr(s string) int {for i := range lastOccurred {lastOccurred[i] = -1}start := 0maxLen := 0for i, ch := range []rune(s) {if lastIndex := lastOccurred[ch]; lastIndex != -1 && lastIndex >= start {start = lastIndex + 1}if i-start+1 > maxLen {maxLen = i - start + 1}lastOccurred[ch] = i}return maxLen
}


优化后,进行性能测试4140482 ns/op;相比上次性能测试的结果,这次更快了!

再次进行分析


现在对图片进行分析就只剩一个必不可少的解码动作比较耗时,其他的都已经完成了优化!

总结

  • 每次进行优化都要先获取性能数据
  • 然后查看性能数据
  • 再分析慢在哪里
  • 优化代码
  • 最后再获取性能数组;循环往复,直到把代码优化到一个比较满意的地步

总之,调优不是一蹴而就的,需要分析,推理,实践,总结,再分析,最终定位到具体的问题

更多推荐

Go学习:pprof性能调优

本文发布于:2023-07-28 19:27:20,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1287143.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:性能   pprof

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!