学习笔记-LEC3-高质量编程与性能调优实践 | 青训营

102 阅读5分钟

LEC3-高质量编程与性能调优实践

本文部分图片资料源自《字节内部课》课程学习资料

高质量编程

编码规范

代码格式

gofmt

Go语言官方提供的工具,能自动格式化Go语言代码为官方统一风格 常见IDE都支持方便的配置

注释

Good code has lots of comments, bad code requires lots of comments

好的代码有很多注释,坏代码需要很多注释

by Dave Thomas and Andrew Hunt

注释应该做的

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

命名规范

缩略词一般全大写

variable

简洁胜于冗长

缩略词全大写,但当其位于变量开头且不需要导出时,使用全小写 例如使用ServeHTTP而不是ServeHttp 使用XML .HT TPRequest或者xmIHT TPRequest

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

全局变量在其名字中需要更多的上下文信息,使得在不同地方可以轻易辨认出其含义

function

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

34点的意思就是比如一个类叫Food

get方法返回Food类,那么Food.get()就行没必要Food.getFood()

大概这么个意思

性能调优指南

使用RaymondCode-对比测试代码

测试方法

go test -bench=. -benchmem

  • -bench=.: 指定运行所有的基准测试。点号(.)表示运行所有的基准测试函数。
  • -benchmem: 在基准测试的报告中包含内存分配的信息。
  • 有点奇怪的是-bench=.跑不了,非得指定函数

b.N变量

image-20230808153331956

在Go语言中,b.N 是在性能基准测试(benchmark testing)中使用的一个变量。基准测试旨在衡量代码在给定工作负载下的性能表现。b.N 表示基准测试框架运行测试函数的次数,框架会根据这个次数来收集足够的数据以计算平均运行时间、内存分配等指标。

在你提供的代码中,BenchmarkFib10 函数定义了一个基准测试。循环体中的 for n := 0; n < b.N; n++ 表示将函数 Fib(10) 运行 b.N 次,基准测试框架会根据这些运行来计算出平均的运行时间以及内存分配情况。在运行基准测试时,b.N 的具体值由基准测试框架动态确定,以便产生准确的性能数据。

要运行这个基准测试,你可以在命令行中使用 go test -bench=. -benchmem 命令。这将会执行当前目录下的所有基准测试,并显示出性能数据,包括每次操作的平均运行时间和内存分配量等。

性能优化建议

预分配内存

  1. 对于slice,map等,在make的时候设定好大小(因为内存拷贝和扩容比较麻烦

  2. 使用copy代替re-slice

字符串处理

使用String.Builder和Byte.Buffer

同时也可用Groe函数预分配空间

空结构体的应用

map值为空结构体来实现set?

atomic包性能优于锁

性能优化分析工具

pprof

pprof是一个性能分析工具,用于分析和可视化Go程序的性能数据。它是Go语言标准库 中的一部分,可以帮助开发人员找出程序中的性能瓶颈、内存使用情况以及其他与性能相关 的问题。pprof 可以生成图形化的性能分析报告,帮助开发人员识别代码中可能存在的性 能问题。 通过pprof,你可以进行以下类型的性能分析:

  1. CPU Profiling: 用于识别程序中的CPU使用热点,即占用大部分CPU时间的代码部分。这对于找出程序中的瓶颈非常有用。
  2. Memory Prfiling: 用于检测内存使用情况,帮助发现内存泄漏和不必要的内存分配。
  3. Block Profiling: 用于分析阻塞操作,例如等待锁或其他资源的情况。
  4. Goroutine Profiling: 用于跟踪Goroutine的创建和销毁情况,以及Goroutine的等待情况。

go的一个性能分析工具

pprof-排查实战

为什么在"net/http/pprof"之前要加"_"?

你提到的 "注意 pprof 相关的 handler 已经自动注册过了" 是指在导入_ "net/http/pprof"这一行之后,Go的net/http/pprof包会自动注册一些与性能分析相关的HTTP处理程序(handlers)到默认的HTTP服务器中,以便在运行时可以通过HTTP接口获取程序的性能分析报告。

这些自动注册的handler包括:

  • /debug/pprof/: 这个路径下包含了各种性能分析报告,如CPU、内存、goroutine、堆栈等。
  • /debug/pprof/cmdline: 显示当前程序的命令行参数。
  • /debug/pprof/profile: 以CPU profile的形式输出CPU使用情况。
  • /debug/pprof/symbol: 符号信息。
  • /debug/pprof/trace: 跟踪信息。

通过在导入语句中使用_来导入net/http/pprof,你的代码可以确保这些性能分析处理程序已经注册到HTTP服务器中,但是你的代码中并不需要显式地调用或引用net/http/pprof中的标识符。这使得你可以通过浏览器或其他工具访问这些路径来查看运行时的性能分析报告,而无需在代码中显式地处理这些HTTP路由。这是一个方便的方式,让你能够轻松地在运行时进行性能分析。

启动后,查看相关指标http://localhost:6060/debug/pprof/