GoLand 2026.1 Help

CPU 分析器

GoLand 会收集并可视化 CPU 分析、跟踪和堆分析数据。 为了收集所有必要的数据,GoLand 使用了 pprof 包。 GoLand 包含四种分析器,您可以通过用户界面运行它们:CPU、内存、阻塞(争用)和互斥锁。

性能分析结果有助于定位性能问题,但代码优化必须手动完成。 有关更多信息,请参阅 go.dev 上的 Profilingpkg.go.dev 上对 pprof 包的介绍

分析完成后,分析器会在报告中可视化显示结果。

在开始之前

在运行性能分析前,请确保:

  • 已安装 Go,您可以使用 GOROOT 文章安装、升级或配置 Go。 欲了解更多信息,请参阅 GOROOT

  • GoLand 已 安装在您的计算机上。

  • 您希望分析的 Go 项目已在 IDE 中打开。

本主题中的所有示例可在 GitHub 上的示例项目中找到。

CPU 分析

CPU 分析器测量程序运行期间每个函数占用的 CPU 时间。

示例程序

以下程序使用低效的冒泡排序算法对随机整数切片进行排序:

package main import ( "fmt" "math/rand" "time" ) func BubbleSort(nums []int) { for i := 0; i < len(nums); i++ { for j := 0; j < len(nums)-i-1; j++ { if nums[j] > nums[j+1] { nums[j], nums[j+1] = nums[j+1], nums[j] } } } } func main() { r := rand.New(rand.NewSource(time.Now().UnixNano())) nums := r.Perm(60000) BubbleSort(nums) fmt.Println("Sorted 60,000 numbers") }

您可以通过 go run main.go 运行此程序,方法是从边栏菜单中选择 运行 选项。

使用冒泡排序运行程序

创建用于分析的测试

创建一个运行排序函数的单元测试:

package main import ( "math/rand" "testing" ) func TestBubbleSort(t *testing.T) { nums := rand.Perm(60000) BubbleSort(nums) }

运行 CPU 分析

  1. 请打开 _test.go 文件。

  2. 点击测试函数旁边边栏菜单中的 运行 选项。

  3. 请选择 使用 CPU Profiler 进行性能分析

    运行 CPU 分析

分析 CPU 分析结果

GoLand 以三种视图呈现 CPU 分析数据:

  • 火焰图 :可视化展示 CPU 时间在各函数间的分布情况。

    火焰图 选项卡显示函数调用及各调用所花时间的百分比。 每个块表示堆栈中的一个函数(一个堆栈帧)。 Y 轴表示堆栈深度(自底向上),X 轴表示按 CPU 使用量从高到低排序的函数。

    阅读火焰图时,请关注最宽的块——它们代表最耗费 CPU 时间的函数。 将鼠标悬停在任意块上可查看详细信息。

    CPU 分析器中的火焰图
  • 调用树 :显示函数之间的调用关系及每次调用所花时间。

    调用树 选项卡提供分析期间采样到的程序调用栈的详细信息。 其中包括:

    • 方法名称

    • 总采样时间的百分比(可切换为显示父调用时间)

    • 采样总数

    • 已过滤的调用次数

    CPU 分析器中的调用树视图
  • 方法列表 :以表格形式显示所有函数的累计执行时间与 CPU 使用百分比。

    方法列表 选项卡列出分析数据中所有方法,按累计采样时间排序。 每个方法项包含一个回溯树和一个合并被调用方法树。

    反向跟踪 选项卡显示调用关系层级,指明调用所选方法的具体来源。 合并被调用方法视图汇总了由所选函数调用的所有方法。

    合并的被调用者 选项卡显示从所选方法开始的调用轨迹。 被调用方列表 是汇总调用层次结构中所有方法的方法列表。

    CPU 分析器中的方法列表视图

在此示例中,大部分时间花在 BubbleSort 的嵌套循环中,这表明存在 O(n²) 性能瓶颈。

优化并比较结果

为提升性能,将冒泡排序替换为快速排序,后者更高效,平均时间复杂度为 O(n log n)。 在测试中,将随机整数数量增加至一千万,以确保排序过程耗时可测——否则算法将几乎立即完成(约 0.01 秒)。

func QuickSort(nums []int) { if len(nums) < 2 { return } quickSortHelper(nums, 0, len(nums)-1) } func quickSortHelper(nums []int, low, high int) { if low < high { pivotIndex := partition(nums, low, high) quickSortHelper(nums, low, pivotIndex-1) quickSortHelper(nums, pivotIndex+1, high) } } func partition(nums []int, low, high int) int { pivot := nums[high] i := low - 1 for j := low; j < high; j++ { if nums[j] <= pivot { i++ nums[i], nums[j] = nums[j], nums[i] } } nums[i+1], nums[high] = nums[high], nums[i+1] return i + 1 }

重新运行 CPU 分析器后,程序运行显著加快并减少了大量 CPU 开销——明显表明性能有所提升。

quicksort-example

为优化后的代码运行基准测试

为确认性能提升,对两个实现版本进行基准测试:

func BenchmarkBubbleSort(b *testing.B) { for i := 0; i < b.N; i++ { nums := rand.Perm(1000) BubbleSort(nums) } } func BenchmarkQuicksort(b *testing.B) { for i := 0; i < b.N; i++ { nums := rand.Perm(1000) QuickSort(nums) } }

基准测试结果表明, Quicksort() 的完成时间远短于 BubbleSort()

BenchmarkQuicksort 和 BubbleSort
2026年 3月 26日