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

49 阅读3分钟

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

重点内容

  1. 如何编写更简洁清晰的代码
  2. 常用Go语言程序优化手段
  3. 熟悉Go程序性能分析工具
  4. 了解工程中性能优化的原则和流程

知识点介绍

  • 什么是高质量

    • 各种边界条件是否完备
    • 异常情况处理,稳定性保障
    • 易读易维护

    ——编写的代码能够达到正确可靠、简洁清晰的目标可称之为高质量代码

  • 编程原则

    • 简单性

      • 消除“多余的复杂性”,以简单清晰的逻辑写代码
      • 不理解的代码无法修复改进
    • 可读性

      • 代码是写给人看的,而不是机器
      • 编写可维护代码的第一步是确保代码可读
    • 生产力

      • 团队整体工作效率非常重要
  • 如何编写高质量代码

    • 代码格式

    • 注释

      • 包中声明的每个公共的符号:变量、常量、函数以及结构都需要添加注释
      • 任何既不明显也不简短的公共功能必须予以注释
      • 无论长度或复杂度如何,对库中的任何函数都必须进行注释
    • 命名规范

      • 简洁胜于冗长
      • 缩略词全部大写,但当其位于变量开头不需要导出时,使用全小写
      • 变量距离其被使用的地方越远,则需要携带越多的上下文信息
    • 控制流程

      • // Bad
        if foo {
            return x
        } else {
            return nil
        }
        // Good
        if foo {
            return x
        }
        return nil
        
      • 正常流程路径为最小缩进
    • 错误和异常处理

      • 不建议在业务代码中使用panic
      • init main函数内中可以使用panic
  • Benchmark

    Go语言提供了支持基准性能测试的benchmark工具

    go test -bench=. -benchmem

  • 性能优化建议

    • slice、map预分配内存
    • 在已有大切片上创建新切片,可以使用copy代替re-slice
    • 使用strings.Builder处理字符串
    • 使用空结构体节省内存(例子,使用map实现set)
    • 使用atomic包,通过硬件实现,效率更高
    • 普通应用代码不要一味追求性能
  • 性能调优原则

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

    • 服务性能评估方式

      • 单独benchmark无法满足复杂逻辑分析
      • 不同负载情况下性能表现差异
    • 请求流量构建

      • 不同请求参数覆盖逻辑不同
      • 线上真实流量情况
    • 压测范围

      • 单机器压测
      • 集群压测
    • 性能数据采集

      • 单机性能数据
      • 集群性能数据

实践

pprof排查实战

常用命令

go tool pprof http://localhost:6060/debug/pprof/profile
go tool pprof http://localhost:6060/debug/pprof/heap
go tool pprof http://localhost:6060/debug/pprof/allocs
名称含义
flat当前函数本身的执行耗时
flat%flat占CPU总时间的比例
sum%上面每一行的 flat% 总和
cum当前函数本身加上其调用函数的总耗时
cum%cum占CPU总时间的比例
  • Flat == Cum,函数没有调用其他函数
  • Flat == 0, 函数只调用了其他函数