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

49 阅读3分钟

高质量编程与性能调优

这是我参与「第五届青训营」伴学笔记创作活动的第3天

1.注释:(解释代码作用,实现,实现原因,代码出错情况,提供代码上下文未体现信息)

1 适合注释公共符号
2 适合注释实现过程
3 适合解释代码实现原因
4 适合解释代码的限制条件

2. 命名规范

variable

  • 简洁胜于冗长
  • 缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写
  • 变量距离其被使用的地方越远,则需要携带越多的上下文信息
  • 全局变量在其名字中需要更多的上下文信息,使得在不同地方可以轻易辨认出其含义

function

  • 函数名不携带包名的上下文信息,因为包名和函数名总是成对出现的
  • 函数名尽量简短
  • 当名为 foo 的包某个函数返回类型 Foo 时,可以省略类型信息而不导致歧义
  • 当名为 foo 的包某个函数返回类型 T 时(T 并不是 Foo),可以在函数名中加入类型信息

package

  • 只由小写字母组成。不包含大写字母和下划线等字符
  • 简短并包含一定的上下文信息。例如 schema、task 等
  • 不要与标准库同名。例如不要使用 sync 或者 strings

3.控制流程

1.避免嵌套
2.保持正常路径为最小缩进(先处理特殊情况)

4.错误和异常处理

1.简单错误
2.错误的Wrap和Unwrap
3.错误判定
4.panic
5.recover-在当前gouroutine的被defer的函数中生效

性能优化建议

benchmark工具

go test -bench=. -benchmem

Slice

预分配内存,使用make()初始化切片提供容量 大内存未释放,用copy代替re-slice(原始切片较大,在基础上建立小切片)

Map

预分配内存,提供容量

strings.Builder

  • 常见的字符串拼接方式

    • “+”
    • strings.Builder
    • bytes.Buffer
  • strings.Builder 最快,bytes.Buffer 较快,+ 最慢

  • 原理

    • 字符串在 Go 语言中是不可变类型,占用内存大小是固定的,当使用 + 拼接 2 个字符串时,生成一个新的字符串,那么就需要开辟一段新的空间,新空间的大小是原来两个字符串的大小之和
    • strings.Builder,bytes.Buffer 的内存是以倍数申请的
    • strings.Builder 和 bytes.Buffer 底层都是 []byte 数组,bytes.Buffer 转化为字符串时重新申请了一块空间,存放生成的字符串变量,而 strings.Builder 直接将底层的 []byte 转换成了字符串类型返回

空结构体

不占内存,可做占位符

atomic包

对比锁,atomic通过硬件实现,效率高

性能调优

  • 要依靠数据不是猜测
  • 要定位最大瓶颈而不是细枝末节
  • 不要过早优化
  • 不要过度优化

pprof工具

功能

实践

    • 前置准备,熟悉简单指标,能够编译运行 pprof 测试项目

    • 实际分析排查过程

      • 排查 CPU 问题

        • 命令行分析

        • top 命令
          flat当前函数本身耗时
          sum上面每一行flat%的总和
          cum 当前函数本身加调用函数总耗时

        • 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]"
  • pprof 的采样过程和原理

    • CPU 采样
    • 堆内存采样
    • 协程和系统线程采样
    • 阻塞操作和锁竞争采样

性能调优

基本问题

为什么要性能优化
性能优化的好处

两个层面

业务层
语言形式

可维护性

开发手段

juejin.cn/course/byte…