【 编码规范和性能优化 | 青训营笔记】

119 阅读2分钟

这是我参与【第五届青训营】伴学笔记创作活动的第三天,此篇概述一下在青训营学习的go语言编程的编码规范以及性能优化方法。

image.png

高质量编程简介及编码规范

  1. 编程原则:简单性、可读性、生产力(团队整体生产效率)

  2. 如何编写高质量的 go 代码

    • 代码格式(推荐使用 gofmt 自动格式化代码)

    • 注释

      • 范围:包中的公共符号、不简单不明显的功能、库中的所有函数
      • 功能:解释代码作用、解释如何实现代码、代码实现的原因、什么情况会出错
    • 命名规范

      • 核心目标是降低阅读理解代码的成本
      • 重点考虑上下文的信息,设计简洁清晰的名称
    • 控制流程

      • 避免嵌套,保持正常流程清晰
      • 尽量保持正常代码路径为最小缩进
    • 错误和异常处理

      1. 简单错误:errors.New() ,如果有格式化需求,使用 fmt.Errorf()

      2. 错误的Wrap和Unwrap:错误的 Wrap 实际上提供一个 error 嵌套另一个 error 的能力,从而生成一个 error 的跟踪链;在 fmt.Errorf中使用 %w 关键字将一个错误关联至错误链中

        list, _, err := c.GetBytes(chane.Subkey(a.actionID, "srcfiles"))
        if err != nil {
            return fmt.Errorf("reading srcfiles list: %w", err)
        }
        
      3. 错误判定:判定一个错误是否为特定错误,使用 errors.ls(err, errtype) , 可判错误链;

        在错误链上获取特定种类的错误,使用 errors.As(err, &pathError)

      4. panic:当程序启动阶段发生不可逆转的错误时才建议使用

      5. recover生效范围: 在当前 goroutine 的被 defer 的函数中生效

性能优化指南

  1. 基准性能测试工具 benchmark

    // this.go
    func Fib(n int) int {
        if n < 2 {
            return n
        }
        return Fib(n-1) + Fib(n-2)
    }
    ​
    // this_test.go
    func BenchmarkFib10(b *testing.B) {
        for n := 0; n < b.N; n++ {
            Fib(10)
        }
    }
    
  2. slice 预分配内存:尽可能在使用 make() 初始化切片时提供容量信息

  3. copy 解决新建小切片原底层大数组在内存中有引用,得不到释放的问题

    // 原切片方法
    func GetBySlice(origin []int) []int {
        return origin[len(orgin)-2:]
    }
    // copy 优化措施
    func GetByCopy(orgin []int) []int {
        result := make([]int, 2)
        copy(result, orgin[len(orgin)-2:])
        return result
    }
    
  4. map 预分配内存:提前预估号需要的空间

  5. 字符串处理:使用 strings.Builder

  6. 空结构体节省内存,可当 set 使用, 如 map[int] struct{}