忽然想起来还没怎么用过 profiling tools,这可是性能分析“杀器”啊,小水一波,兴许以后就用上了🙃。
profiling,分析。有很多时候,我们都会相对处于 runtime 的程序进行指标 & 特征分析,比如 CPU 使用情况、内存使用情况,race 检测等。
Flame Graph,火焰图。火焰图是一种常用的可视化分析性能数据的方式。不同类型火焰图适合不同的性能分析优化场景。
上图为 CPU 使用情况的 Flame Graph,来自 -> (https://github.com/brendangregg/FlameGraph。通过该图,我们可以找到 CPU 占用最多的函数,分析代码热路径。特征如下:
值得注意的是:横轴先后顺序是为了聚合,跟函数间依赖或调用关系无关;一般情况下,火焰图各种颜色是为方便区分,本身不具有特殊含义。
根据这篇 Toturial -> Profiling Elixir Applications with Flame Graphs and Flame On,我们在 Phoenix App Telemetry Dashboard 中集成 Flame On,GET 到如下 Flame Graph:
Go 内置了 profiling 工具 [pprof][https://github.com/google/pprof] 方便我们对程序进行分析,通过 runtime/pprof 包,我们可以在程序中指定位置埋下采集点。
package main
import (
"math/rand"
"os"
"runtime/pprof"
"time"
)
func generate(n int) []int {
rand.Seed(time.Now().UnixNano())
nums := make([]int, 0)
for i := 0; i < n; i++ {
nums = append(nums, rand.Int())
}
return nums
}
func insertionSort(nums []int) {
var n = len(nums)
for i := 1; i < n; i++ {
j := i
for j > 0 {
if nums[j-1] > nums[j] {
nums[j-1], nums[j] = nums[j], nums[j-1]
}
j = j - 1
}
}
}
func main() {
profileFile, _ := os.OpenFile("cpu.pprof", os.O_CREATE, 0644)
defer profileFile.Close()
pprof.StartCPUProfile(profileFile)
defer pprof.StopCPUProfile()
var n int = 10
for i := 0; i < 5; i++ {
nums := generate(n)
insertionSort(nums)
n *= 100
}
}
go run main.go # 生成 cpu.pprof profiling 文件
# 启动 http server 查看分析数据
go tool pprof -http=:8080 cpu.pprof
然后可以 GET 到类似如下得 Flame Graphs,就挺不 Simplex 的,2333:
React App 的 profiling 我们可以借助浏览器扩展 React DevTools 进行,也可以在使用官方提供的 Profiler API.
我们起个 Ant-Design Pro 来看看:https://github.com/ant-design/ant-design-pro
yarn create umi