静态分析 | 青训营笔记

115 阅读2分钟

静态分析

不执行程序代码,推到程序的行为,分析程序的本质

数据流和控制流

数据流: 数据在控制流上的传递

  • 通过语义分析控制流和数据流可以知道更多关于程序的本质

控制流: 程序执行的流程

过程内和过程间分析

过程内分析: 仅在函数内部进行分析

过程间分析: 考虑函数调用时参数传递和返回值的数据流和控制流

编译器优化

目的

  • 用户无感知,重新编译即可获得性能收益
  • 通用性优化

函数内联

如果程序中存在大量的小函数的调用,函数内联就会直接用函数体替换掉函数调用来减少因为函数调用而造成的额外上下文切换开销

内联: 将被调用函数的函数体的副本替换到调用位置上,同时重写代码以反映参数的绑定

优点

  • 消除函数调用开销,例如传递参数、保存寄存器等
  • 将过程间分析转化为过程内分析,帮助其他优化,例如逃逸分析

缺点

  • 函数体变大
  • 编译生成的go镜像变大

大多数情况内联是正向优化

逃逸分析

分析代码中指针的动态作用域:指针在何处可以被访问

步骤

  1. 从对象分配处出发,沿着控制流观察对象的数据流

  2. 若发现指针p在当前作用域s

    • 作为参数传递给其他函数
    • 传递给全局变量
    • 传递给其他的goroutine
    • 传递给已逃逸的指针指向的对象
  3. 则指针p指向的对象逃逸出s,反之则没有逃逸出s

优化: 未逃逸出当前函数的指针指向的对象可以在栈上分配

  • 对象在栈上分配和回收很快:移动sp

  • 减少在heap上的分配,降低GC负担