【高质量编程与性能调优实战】丨青训营笔记

119 阅读3分钟

第三节课【高质量编程与性能调优实战】

这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记

高质量编程

代码格式

使用编译器自动格式化

注释

一定要记得对代码进行注释

公共符号:变量、常量、函数以及结构都需要添加注释

私有的功能则看情况注释

  • 注释应该做的

    • 注释应该解释代码作用
    • 注释应该解释代码如何做的
    • 注释应该解释代码实现的原因
    • 注释应该解释代码什么情况会出错

命名规范

variable

简洁胜于冗长

缩略词需要全大写,但如果其位于变量开头且不需要导出时,使用全小写

变量距离被使用的地方越远则需携带更多上下文信息

function

不需要携带包名信息(因为包名和函数名总是成对出现)

尽量简短

package

只由小写字母组成,且不包含下划线

简短并包含一定上下文信息

不与标准库同名

使用单数而不是复数

性能优化

slice预分配内存

在预知slice最终大小的时候,尽可能在使用make初始化切片时提供容量信息

slice内存陷阱

当需要切片中的切片时,尽量新建一个切片后使用copy函数进行复制,而不是直接返回切片的切片。

原因:当以切片创建切片时,其实并没有创建新的底层数组,新的切片只是对原来切片的引用,如果只需要新的切片,则由于旧的切片一直被引用,会有很大一部分内存空间将会被浪费

map预分配内存

同切片类似,在预知map最终大小的时候,也可以在make初始化时预分配内存

字符串处理

使用strings.Builder拼接字符串,要优于使用 “+” 和bytes.Buffer

拼接时:

“+” 每次拼接字符串都需要重新分配内存,strings.Builder和bytes.Buffer底层都是[]byte数组,有内存扩容策略

转化为字符串时:

bytes.Buffer转化为字符串时重新申请了一块空间,而strings.Builder直接将[]byte类型转化为string类型

使用空结构体节省内存

如:实现set

可用map代替,键为需要的变量类型,值为空结构体

使用atomic包

锁的实现是通过操作系统来实现,属于系统调用

atomic操作则通过硬件实现,效率比锁高

性能调优

排查工具

运行课程代码后,可进入localhost查看性能指标

运行时间

终端输入:go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"

可再输入:

top:查看占用资源最多的函数

list + (函数名): 查找代码行

web :查看关系可视化图(须先安装Graphviz,下载地址:Download | Graphviz

堆内存

终端输入: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"