这是我参与「第五届青训营 」笔记创作活动的第五天
高质量编程与性能调优
一、高质量编程及编码规范
1、简单性
- 消除多余的复杂性,以简单清晰的逻辑编写代码
- 不理解的代码无法修复改进
2、可读性
- 代码是给人看的 而不是机器
- 编写可维护的代码 第一步是保证代码可读
3、生产力
团队整体工作效率很重要
推荐使用gofmt自动格式化代码
注释
- 包中声明的每个公共的符号:变量、常量、函数以及结构都需要添加注释
- 任何既不明显也不简短的公共功能必须予以注释
- 无论长度或复杂程度如何对库中的任何函数都必须进行注释
- 注释应该做的
- 解释代码作用
- 解释代码如何做的
- 解释代码实现的原因
- 解释代码什么情况会出错
命名
- 变量
- 简洁胜于元长
- 缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写
- 例如使用 ServeHTTP 而不是 ServeHttp、使用 XMLHTTPRequest 或者 xmIHTTPRequest
- 变量距离其被使用的地方越远,则需要携带越多的上下文信息
- 全局变量在其名字中需要更多的上下文信息,使得在不同地方可以轻易辨认出其含义
- 函数
- 函数名不携带包名的上下文信息,因为包名和函数名总是成对出现的
- 函数名尽量简短
- 当名为 foo 的包某个函数返回类型 Foo 时,可以省略类型信息而不导致歧义
- 当名为 foo 的包某个函数返回类型 T 时 (T 并不是 Foo) ,可以在函数名中加入类型信息
- 包
- 只由小写字母组成。不包含大写字母和下划线等字符
- 简短并包含一定的上下文信息。例如 schema、task 等
- 不要与标准库同名。例如不要使用 sync 或者 strings
控制流程
- 避免使用嵌套
- 优先处理错误情况/特殊情况,尽早返回或继续循环减少嵌套
二、性能优化
- 尽量在使用make()初始化切片时提供容量信息
- 在已有切片基础上创建切片,不会创建新的底层数组,原底层数组在内存中有引用得不到释放
- 可是使用copy代替re-slice
- 字符串拼接
- 使用普通的+性能最差
- 使用strings.builder和bytes.buffer性能会提高很多
- 字符串也可以预分配内存
- 空结构体不占用任何内存
- sync.Mutex应该用来保护一段逻辑,当用于保护一个变量时可以使用atomic包。
性能优化分析工具
性能优化原则
- 要依靠数据而不是猜测
- 要定位最大瓶颈而不是细节末节
- 不要过早优化
- 不要过度优化
pprof
性能优化案例
- 业务服务优化
- 基础库优化
- Go语言优化
业务服务优化流程
- 建立服务性能评估手段
- 分析性能数据,定位性能瓶颈
- 重点优化项改造
- 优化效果验证
基础库优化
基础库优化即使效果不明显 但如果在公司内大范围使用,仍然可以节省很多资源
Go语言优化
- 优点
- 接入简单,只需要调整接入配置
- 通用性强
总结
- 性能优化并没有想象的那么困难,掌握方法,用好工具就好
- 但要保证优化的正确性