这是我参与「第五届青训营」伴学笔记创作活动的第 3天
本节内容
-
高质量编程
- 高质量编程简介
- 编程规范
- 编程优化建议
-
性能调优实战
- 性能调优简介
- 性能分析工具pprof实战
高质量编程
1.1高质量编程简介
- 各种边界情况是否考虑完备
- 各种情况处理,稳定性保证
- 易读以维护
简单性
- 消除“多余的复杂性”,以简单清晰的逻辑编写代码
- 不理解的代码无法修复改进
可读性
生产力
1.2 编程规范
编程规范---注释
注释应该做的
- 注释应该解释代码的作用
- 注释应该解释代码任何做的
- 注释应该解释代码实现的原因
- 注释应该解释代码什么情况会出错
编程规范----命名规范
-
简洁胜于冗长
-
缩略饲全大写,但当其位于变量开头且不需要导出时,使用全小写
- 例如使用ServeHTTP而不是ServeHttp
- 使用MLHTTPRequest或者xmlHTTPRequest
- 变量距离其被使用的地方越远,则需要携带越多的上下文信息 全局变量在其名字中需要更多的上下文信息,使得在不同地方可以轻易辨认出其含义
- ·函数名不携带包名的上下文信息,因为包名和函数名总是成对出现的
- 函数名尽量简短
- 当名为foo的包某个函数返回类型Fo0时,可以省略类型信息而不导致歧义
- 当名为f00的包某个函数返回类型T时(T并不是Foo),可以在函数名中加入类型信息
编程规范----错误和异常处理
》简单错误
- 简单错误是指只出现一次的错误,并且其它地方不需要捕获该错误
- 优先使用error.Now来创建匿名变量来简单表示错误
- 有格式化要求使用fmt.Errorf
性能优化建议
slice 预分配内存
- 在使用make()函数时尽可能的提供容量信息
另一个陷阱:大内存未释放
map预分配内存
- 不断向map中添加元素的操作会触发map的扩容
- 提前分配好空间可以减少内存拷贝和Rehash的消耗
- 建议根据实际需求提前预估好需要的空间
字符串处理
-
使用+拼接性能最差,strings.Builder,bytes.Buffer相近,strings.Buffer更快
-
·分析
- ·字符串在G0语言中是不可变类型,占用内存大小是固定的
- 使用+每次都会重新分配内存
- strings.Builder,bytes..Buffer底层都是[]byte数组
- 内存扩容策略,不需要每次拼接重新分配内存
空结构体
因此可以使用map来实现set
atomic包
使用atomic包
- 锁的实现是通过操作系统来实现,属于系统调用
- atomic操作是通过硬件实现,效率比锁高
- sync.Mutex应该用来保护一段逻辑,不仅仅用于保护一个变量
- 对于非数值操作,可以使用atomic..Value,能承载一个interface{}
性能分析工具pprof
可以在浏览器中localhost:6060/debug/pprof看项目的性能分析
实际分析排查过程
-
排查 CPU 问题
-
命令行分析
- go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"
-
top 命令
- 可以看代码中什么是占用最高的
-
list 命令
- list 函数名 可以看函数中是那一句占用资源最高
-
熟悉 web 页面分析
-
调用关系图,火焰图
-
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/cpu"
-
-
排查堆内存问题
- go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
-
排查协程问题
- go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
-
排查锁问题
- go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
-
排查阻塞问题
- go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"