查看原文
其他

Go 语言持续基准测试:精准追踪性能,优化代码效率

源自开发者 源自开发者
2024-08-28

在软件开发领域,性能优化是一个永恒的话题。为了追求极致的用户体验,开发者们不断探索各种技术手段,力求让代码运行得更快、更节省资源。而基准测试作为评估代码性能的重要工具,在持续集成和持续交付流程中扮演着不可或缺的角色。本文将深入探讨如何在 Go 语言项目中高效地集成持续基准测试,并以追踪内存消耗为例,带你领略持续基准测试的魅力。

持续基准测试的意义

1. 及早发现性能回退

在代码迭代过程中,难免会引入新的性能问题。持续基准测试可以帮助我们在每次代码变更后自动运行基准测试,并将结果与历史数据进行比较,从而尽早地发现潜在的性能回退。

2. 追踪历史数据

仅仅查看当前的基准测试结果是不够的,我们需要了解代码性能随时间的变化趋势。持续基准测试可以帮助我们记录每次测试的结果,并生成可视化的图表,方便我们分析性能变化趋势,找出潜在的性能瓶颈。

3. 比较分析,识别性能瓶颈

持续基准测试可以帮助我们对不同代码版本、不同代码路径进行性能比较,从而识别出代码中效率较低的代码块,为后续优化提供依据。

Go 语言内存消耗追踪实战

以一个简单的 Go 函数为例,该函数用于获取点赞数:

func GetLikes(userID int) int {
 // 模拟数据库查询
 time.Sleep(10 * time.Millisecond)
 return rand.Intn(1000)
}

func BenchmarkGetLikes(b *testing.B) {
 for i := 0; i < b.N; i++ {
  GetLikes(123)
 }
}

我们可以使用以下命令运行基准测试,并获取内存分配信息:

go test -run=notests -count 1 -bench=BenchmarkGetLikes ./... -benchmem | grep allocs

输出结果类似于:

348    3426515 ns/op  2957280 B/op    19169 allocs/op
                           ↑ 目标值 ↑

其中:

  • 348:基准测试迭代次数。
  • 3426515 ns/op:每次操作平均耗时,单位为纳秒。
  • 2957280 B/op:每次操作平均分配的字节数,即我们关注的目标值。
  • 19169 allocs/op:每次操作平均内存分配次数。

为了持续追踪每次操作的内存消耗,我们可以使用以下命令:

go test -count 1 -bench=. ./... -benchmem | grep allocs | awk '{ print $4/1024/1024 }'

该命令将输出每次操作平均分配的兆字节数。

集成持续集成

为了将基准测试集成到持续集成流程中,我们可以使用 GitHub Actions。以下是一个简单的示例:

name: Go 持续基准测试

on:
 push:
  branches:
   - main
 pull_request:
  branches:
   - main

jobs:
 benchmark:
  runs-on: ubuntu-latest
  steps:
   - name: Checkout 代码
    uses: actions/checkout@v2

   - name: 设置 Go 环境
    uses: actions/setup-go@v2
    with:
     go-version: 1.18

   - name: 运行基准测试
    run: |
     go test -count 1 -bench=. ./... -benchmem | grep allocs | awk '{ print $4/1024/1024 }' > benchmark.txt

   - name: 上传基准测试结果
    uses: actions/upload-artifact@v2
    with:
     name: benchmark-results
     path: benchmark.txt

   - name: 分析基准测试结果
    uses: kevincobain2000/action-coveritup@v2
    with:
     type: get-likes-mem/op
     command: cat benchmark.txt
     record: score
     metric: MB
     pr_comment: true

该 workflow 文件定义了以下步骤:

  1. 当代码被 push 到 main 分支或创建 Pull Request 时触发 workflow。
  2. 使用 actions/checkout@v2 action 检出代码。
  3. 使用 actions/setup-go@v2 action 设置 Go 环境。
  4. 运行基准测试并将结果保存到 benchmark.txt 文件中。
  5. 使用 actions/upload-artifact@v2 action 上传 benchmark.txt 文件作为 artifact。
  6. 使用 kevincobain2000/action-coveritup@v2 action 分析基准测试结果,并将其作为评论添加到 Pull Request 中。

总结

持续基准测试是保障代码性能的重要手段,它可以帮助我们及早发现性能回退、追踪历史数据、识别性能瓶颈。在 Go 语言项目中,我们可以借助丰富的工具和框架,轻松地集成持续基准测试,为代码性能保驾护航。

文章精选

使用 Go 语言连接并操作 SQLite 数据库

Go语言官方团队推荐的依赖注入工具

替代zap,Go语言官方实现的结构化日志包

Go语言常见错误 | 不使用function option模式

必看| Go语言项目结构最佳实践


点击关注并扫码添加进交流群
领取「Go 语言」学习资料

继续滑动看下一个
源自开发者
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存