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

85 阅读4分钟

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

一.高质量编程 ,编码规范, 性能优化建议。

什么是高质量, 可靠正确,简洁清晰 各种边界条件是否考虑完备,异常情况处理,稳定性保证, 易读易维护,下游代码是否好处理

编程原则

  • 简单性

    消除多余的复杂性,以简单清晰的逻辑编写代码,不好定位,不好改动

  • 可读性

    代码是给人看的

    编写可维护代码第一步是确保代码可读

  • 生产力

    团队整体工作效率很重要,用工具统一代码格式。

编码规范

  • 代码格式

    • gofmt自动格式化代码,官方推荐工具,常见ide都支持
    • goimports 自动增删依赖的包引用
  • 注释

    • 注释应该解释代码作用

    • 应该解释代码如何做的

    • 代码实现原因

      • 适合解释代码的外部因素
      • 提供额外上下文
    • 什么情况会出错

      • 适合解释代码的限制条件

      公共符号始终要注释

      有一个例外,不需要注释实现接口的方法

    好的代码有很多注释,代码是最好的注释,注释应提供代码为表达出的上下文信息

  • 命名规范

    • variable

      • 简洁胜于冗长
      • 缩略词全大写,但档期位于变量开头且不需要到处时,使用全小写
      • 变量距离其被使用的地方越远,则需要越多的上下文信息
    • function

      • 函数名不懈怠报名的上下文信息,因为包名和函数名总是成对出现的
      • 函数名尽量简短
      • 当包名某个函数和返回类型相同时,可以省略类型信息而 不导致歧义
    • package

      • 只由小写字母组成,不包含大写字母和下划线
      • 简短并包含一定上下文信息
      • 不要与标准库同名
      • 尽量不适用常用变量作为包名
      • 使用单数而不是复数
      • 谨慎的使用缩写

      小结:降低阅读理解代码的成本

      重点考虑上下文信息,设计简洁清晰的名称

  • 控制流程

    • 避免嵌套
    • 尽量保持正常代码路劲为最小缩进
小结:线性原理,避免复杂嵌套分支,故障大多出现在复杂的条件和循环语句中。
  • 错误异常处理

    • 简单错误:优先使用errors.New

    • 错误的Wrap和Unwrap

    • 错误判定

      • 判定一个错误是否为特定错误,erros.Is
      • 再错误链上获取特定种类的错误,使用errors.As
      • panic:不见以在业务中使用panic
    • recover

      • 只能在被defer的函数中使用
      • 嵌套无法生效
      • 旨在当前goroutine生效
      • defer后进先出
    小结:error尽可能提供简明的上下文信息链,方便定位问题

    panic用于真正异常的情况

    recover生效范围,在当goroutine的被的defer的函数中生效

二.性能调优简介

前提:正确可靠,简洁清晰等质量因素

  • 如何使用

    • 性能表现需要时机数据衡量
    • Go语言提供基准性能测试benchmark工具
  • slice预分配内存

    • 尽可能在使用make()初始化切片时提供容量信息
    • 另一个陷阱:大内存未释放,可用copy替代re-slice,因为如果原底层数组在内存中有引用,得不到释放
  • map预分配内存

  • 字符串处理

    • 使用strings.Builder,+每次重新分配内存,其他两个有内存扩容策略,Builder效率好点

      预先分配内存效率会更高

  • 空结构体

  • atomic包

    • 性能比加锁高 !

image.png 小结:

-   避免常见性能陷阱
-   不要一味追求程序性能
-   越高级的性能优化手段越容易出现问题
-   在满足正确可靠,简洁清晰的质量要求的前提下提高程序性能

性能分析工具pprof

  • 性能调优原则

    • 依靠数据不是猜测
    • 定位最大瓶颈不是细枝末节
    • 不要过早优化
    • 不要过度优化
  • 浏览器查看指标

image.png

可以在go tool pprof 后加上-http=:8080 再加上”httpxxx"可以可视化
  • 火焰图

    • 从上到下表示调用顺序
    • 每一块代表一个函数,越长代表占用cpu时间更长
    • 火焰图是动态的,支持点击块进行分析
  • 采样过程和原理

三.性能调优案例

  • 业务服务优化

    • 建立服务性能评估手段
    • 重点优化项改造
    • 优化效果验证
    • 进一步优化,服务整体链路分析
  • 基础库优化

    • AB实验SDK的优化

      • 基础库核心逻辑和性能瓶颈
      • 内部压测验证
      • 推广业务服务落地验证
  • Go语言优化

    • 编译器&运行时优化

总结

性能调优原则

  • 要依靠数据不是猜测

性能分析工具pprof

image.png

性能调优

  • 保证正确性
  • 定位主要瓶颈