关于 golang-performance
面向 Go 工程师和编码 Agent 的性能审查与优化技能,强调先分析性能剖析数据,再逐项修改并通过基准测试验证效果。
主要功能
- 01架构与热点路径审查模式
- 02基于性能剖析的瓶颈诊断
- 03迭代式基准测试与结果比较
- 04内存、CPU、I/O、运行时及缓存建议
- 05CI 基准测试回归检查
适用场景
- 01审查 Go 服务的结构性性能问题
- 02调查已定位的热点函数
- 03使用 benchstat 验证优化效果
- 04在 CI 中加入基准测试回归检查
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ samber/ cc-skills-golang --skill golang-performance安装后在 Claude Code 中输入/golang-performance确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/prometheus-alerts.ymlevals/evals.jsonreferences/caching.mdcpu.mdio-networking.mdmemory.mdobservability.mdruntime.md详细介绍
角色设定: 你是一名 Go 性能工程师。绝不在分析性能配置前进行优化——先测量、提出假设、只改一处,然后重新测量。
思考模式: 进行性能优化时,尽可能彻底地推理——浅层分析会误判瓶颈,深入推理才能确保针对正确的问题应用正确的优化。在 Claude Code 中,使用 ultrathink 显式触发扩展思考。
编排模式: 启动架构审查模式中描述的三个子 Agent(内存分配和内存布局、I/O 和并发、算法复杂度和缓存),进行全面的架构性能审查。单个热点路径审查应按顺序进行;只有在包或服务范围内,分派多个 Agent 才有意义。在 Claude Code 中,使用 ultracode 显式启用多 Agent 编排。
模式:
- 审查模式(架构) — 全面扫描包或服务,查找结构性反模式(缺少连接池、无界 goroutine、错误的数据结构)。最多使用 3 个并行子 Agent,分别负责以下方面:(1)内存分配和内存布局;(2)I/O 和并发;(3)算法复杂度和缓存。
- 审查模式(热点路径) — 针对调用方指出的单个函数或紧密循环进行分析。按顺序进行;一个子 Agent 即可。
- 优化模式 — 已通过性能分析识别出瓶颈。按顺序执行迭代周期(定义指标 → 基准测试 → 诊断 → 改进 → 比较)——一次只做一项改动。
依赖项:
- benchstat:
go install golang.org/x/perf/cmd/benchstat@latest
Go 性能优化
核心理念
- 先分析性能,再进行优化 — 对瓶颈的直觉判断有约 80% 的概率是错的。使用 pprof 找出实际热点(→ 参见
samber/cc-skills-golang@golang-troubleshooting技能) - 减少内存分配的投资回报率最高 — Go 的 GC 很快,但并非没有成本。减少每个请求的内存分配,往往比微优化 CPU 更重要
- 记录优化原因 — 添加代码注释,解释某种模式为何更快;如有基准测试数据,也应一并注明。后续读者需要这些背景信息,避免撤销“多余的”优化
先排除外部瓶颈
优化 Go 代码前,先确认瓶颈在你的进程内——如果 90% 的延迟来自缓慢的 DB 查询或 API 调用,减少内存分配也无济于事。
诊断: 1- fgprof — 同时捕获 CPU 执行时间和 CPU 非运行时间(I/O 等待);如果 CPU 非运行时间占主导,瓶颈就在外部 2- go tool pprof(goroutine 性能分析)— 大量 goroutine 阻塞在 net.(*conn).Read 或 database/sql 中,说明存在外部等待 3- 分布式追踪(OpenTelemetry)— span 分解结果会显示哪个上游较慢
如果瓶颈在外部: 改为优化相应组件——查询调优、缓存、连接池、熔断器(→ 参见 samber/cc-skills-golang@golang-database 技能、缓存模式)。
迭代优化方法
完整流程:定义目标 → 基准测试 → 诊断 → 改进 → 基准测试
- 定义指标 — 延迟、吞吐量、内存还是 CPU?没有目标,优化就会变成盲目尝试
- 编写原子化基准测试 — 每个基准测试只隔离一个函数,避免结果受到干扰(→ 参阅
samber/cc-skills-golang@golang-benchmark技能) - 测量基线 —
go test -bench=BenchmarkMyFunc -benchmem -count=6 ./pkg/... | tee /tmp/report-1.txt - 诊断 — 使用每个深入分析章节中的 诊断 行,选择合适的工具
- 改进 — 一次只应用一项优化,并添加解释性注释
- 比较 — 使用
benchstat /tmp/report-1.txt /tmp/report-2.txt确认统计显著性 - 提交 — 将 benchstat 输出粘贴到提交说明正文中,让审阅者和未来的读者看到确切的改进;遵循
perf(scope): summary提交类型 - 重复 — 递增报告编号,处理下一个瓶颈
在自行设计解决方案之前,请先查阅库文档,了解已知模式。保留所有 /tmp/report-*.txt 文件,作为审计记录。
当多个候选优化方案争夺解决同一个瓶颈时,应通过独立的子 Agent,在各自隔离的 worktree 中实现每个方案——然后 → 参阅 samber/cc-skills-golang@golang-benchmark 技能,了解如何比较各个方案及其串行测量注意事项(在共享 CPU 上并发运行基准测试会污染结果,即使各方案的实现是在并行构建的)。
决策树:时间花在哪里?
| 瓶颈 | 信号(来自 pprof) | 操作 |
|---|---|---|
| 分配次数过多 | 堆分析中 alloc_objects 数值偏高 | 内存优化 |
| CPU 密集型热循环 | 某个函数在 CPU 分析中占主导地位 | CPU 优化 |
| GC 暂停 / OOM | GC% 偏高、容器限制 | 运行时调优 |
| 网络 / I/O 延迟 | goroutine 阻塞在 I/O 上 | I/O 与网络 |
| 重复执行开销大的工作 | 多次执行相同计算 / 获取操作 | 缓存模式 |
| 算法错误 | 存在 O(n) 算法,却使用 O(n²) 算法 | 算法复杂度 |
| 锁竞争 | mutex / block 分析热点 | → 参阅 samber/cc-skills-golang@golang-concurrency 技能 |
| 查询缓慢 | 跟踪中 DB 时间占主导地位 | → 参阅 samber/cc-skills-golang@golang-database 技能 |
常见错误
| 错误 | 修正方法 |
|---|---|
| 未进行分析就优化 | 先用 pprof 分析——大约 80% 的情况下,直觉都是错的 |
使用没有 Transport 的默认 http.Client | MaxIdleConnsPerHost 的默认值为 2;应设置为与并发级别相匹配 |
| 在热循环中记录日志 | 日志调用会阻止内联,即使日志级别已禁用也会分配内存。请使用 slog.LogAttrs |
将 panic/recover 用作控制流 | panic 会分配堆栈跟踪并展开堆栈;请使用错误返回值 |
没有基准测试证明就使用 unsafe | 只有在分析确认某个热点路径的性能提升超过 10% 时才合理 |
| 未在容器中调优 GC | 将 GOMEMLIMIT 设置为容器内存的 80-90%,以防止因 OOM 被终止 |
在生产环境中使用 reflect.DeepEqual | 比类型化比较慢 50-200 倍;请使用 slices.Equal、maps.Equal、bytes.Equal |
深入分析
- 内存优化 — 分配模式、底层数组泄漏、sync.Pool、结构体对齐
- CPU 优化 — 内联、缓存局部性、伪共享、ILP、避免反射
- I/O 与网络 — HTTP 传输配置、流式处理、JSON 性能、cgo、批量操作
- 运行时调优 — GOGC、GOMEMLIMIT、GC 诊断、GOMAXPROCS、PGO
- 缓存模式 — 算法复杂度、编译后的模式、singleflight、避免重复工作
- 生产环境可观测性 — Prometheus 指标、PromQL 查询、持续分析、告警规则
CI 回归检测
在 CI 中自动比较基准测试结果,确保回归问题不会进入生产环境。→ 参见 samber/cc-skills-golang@golang-benchmark 技能,了解 benchdiff 和 cob 的设置。
交叉引用
- → 参见
samber/cc-skills-golang@golang-benchmark技能,了解基准测试方法、benchstat和b.Loop()(Go 1.24+) - → 参见
samber/cc-skills-golang@golang-troubleshooting技能,了解 pprof 工作流、逃逸分析诊断和性能调试 - → 参见
samber/cc-skills-golang@golang-data-structures技能,了解切片/映射预分配和strings.Builder - → 参见
samber/cc-skills-golang@golang-concurrency技能,了解工作池、sync.PoolAPI、goroutine 生命周期和锁竞争 - → 参见
samber/cc-skills-golang@golang-safety技能,了解循环中的 defer、切片底层数组别名 - → 参见
samber/cc-skills-golang@golang-database技能,了解连接池调优和批处理 - → 参见
samber/cc-skills-golang@golang-observability技能,了解生产环境中的持续性能分析