GO 性能分析

news2024/12/27 9:32:45

GO 性能分析

简介

​ go提供了内存分析工具,pprof利用它可以看cpu和内存的情况。

包含下面的几种类型:

  • cpu
  • 内存
  • 阻塞

pprof分为大体分为两个部分

  1. 数据采集
  2. 数据分析

数据采集有两种方式:

  1. 官方

    官方提供了两种方式

    • runtime/pprof

      这是用来给没http服务来使用

      https://pkg.go.dev/runtime/pprof

    • net/http/pprof

      给http服务来使用的,提供了路由来方便访问。

      https://pkg.go.dev/net/http/pprof

  2. 三方库

    • profile

      https://github.com/pkg/profile

数据分析:

  1. go tool pprof

    官方文档:https://github.com/google/pprof

使用

数据采集

cpu

启动 CPU 分析时,运行时(runtime) 将每隔 10ms 中断一次,记录协程(goroutines) 的堆栈信息。一个函数在性能分析数据中出现的次数越多,说明执行该函数的代码路径(code path)花费的时间占总运行时间的比重越大。

  1. 代码

    package main
    
    import (
    	"fmt"
    	_ "net/http/pprof"
    	"os"
    	"runtime/pprof"
    )
    
    func main() {
    	// 手动创建pprof文件
    	f, err := os.Create("cpu_test.pprof")
    	if err != nil {
    		return 
    	}
    	// 启动
    	if err := pprof.StartCPUProfile(f); err != nil {
    		return 
    	}
    	//defer 停止
    	defer pprof.StopCPUProfile()
    	
    	var a []int
    
    	for i := 0; i < 100000; i++ {
    		a = append(a, i)
    	}
    	res := twnSum(a, len(a)*3)
    	fmt.Printf("%v",res)
    }
    func twnSum(data []int,sum int) []int  {
    	for i, itemA := range data {
    		for i2, itemB := range data {
    			if i == i2{
    				continue
    			}
    			if itemA + itemB == sum{
    				return []int{i,i2}
    			}
    		}
    	}
    	return nil
    }
    

    这种方式是我用原生库实现的,开启方式在原生库的文档里面有,分为下面三步:

    • 创建pprof文件
    • 启动cpu profile
    • 在defer中停止cpu profile

    运行此代码

     go run .\main.go
    

    在项目的根目录下面会有cpu_test.pprof,到此数据采集一级成功,分析在后面章节会介绍。

    三方库也是对基本代码的再次包装

profile库实现方式
// 主体代码都一样,采集的代码不一样
	defer profile.Start().Stop()

就这一行,开启了cpu profile,看看它做了什么事情。

在这里插入图片描述

  1. 返回了一个接口,接口里面有stop方法
  2. 通过options(入参)来配置prof
  3. 选择模式
  4. 这代码是上面用pprof包做的事情

它支持的模式有:

在这里插入图片描述

从代码可以看到,在调用start方法的时候可以通过入参来配置Profile,它的入参是func的可变切片。我们可以自定义,同时它提供了一些方法便于我们操作:

在这里插入图片描述

使用方式如下:

	defer profile.Start(
		profile.CPUProfile,
		profile.ProfilePath("D:/GolandProjects/base_go/pprof"),
		).Stop() // 指定采集类型为CPU,并且指定pprof文件的路径

内存

内存性能分析(Memory profiling) 记录堆内存分配时的堆栈信息,忽略栈内存分配信息。

它也有采样比,默认是每分配512KB的时候采样一次,每次都需要采样的时候设置为1,不需要的时候设置为0。

这里我们直接用profile包来做

//主体代码都一样,只是profile变化
defer profile.Start(profile.MemProfile).Stop()

在log里面会显示pprof文件的目录。

数据分析

有两种方式

  1. web界面
  2. 交互界面

文档:https://github.com/google/pprof/blob/main/doc/README.md

这个文档解释了命令行和图形化中字段的含义。在下面的例子中我会对部分做解释说明。

web界面

需要安装Graphviz

官网:https://graphviz.org/

启动方式:

go tool pprof -http=:9989 .\cpu_test.pprof
// 格式如下
go tool pprof -http=主机:端口 pprof文件

访问localhost:9989界面如下:

在这里插入图片描述

说明:web界面也是将命令行的显示图形化,两者是一样,在这里做详细的解释之后,命令行就不多做解释了。

界面元素解释如下:

官网:https://github.com/google/pprof/blob/main/doc/README.md#interpreting-the-callgraph

view界面

文档:https://github.com/google/pprof/blob/main/doc/README.md#view

在这里插入图片描述

top

在这里插入图片描述

Graph

在这里插入图片描述

Flame

在这里插入图片描述

命令行交互界面

go tool pprof  C:\Users\liuchen\AppData\Local\Temp\profile4178991121\cpu.pprof

其余的命令行操作看官方文档

要解释一下Flat和Cum

文档上是这么说的:

在这里插入图片描述

我理解是:

pprof的数据是通过采样获取的,并且数据要有垂直结构,每个采样点都有自己的代价和它所有的调用方法包括一块的代价

flat:采样点自己的代价。

cum:采样点调用方法一块的代价。

http服务

数据采集

原生go http服务方式

前提:启动http服务,用go原生的(非必须,之后可以自己做自定义)

package main

import (
	"fmt"
	"log"
	"net/http"
	_ "net/http/pprof"
)

func handler(w http.ResponseWriter, r * http.Request) {
	fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
	http.HandleFunc("/", handler)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

导入net/http/pprof

import _ "net/http/pprof"

访问 http://localhost:8080/debug/pprof/看到下面的页面就说明ok了。我们就可以获取对应的pprof报告了。

在这里插入图片描述

使用方式和源码分析

看到这种导包方式,就知道在init方法里面干了一些事情。

在这里插入图片描述

可以看到,在init里面它自己注册了几个路由,每一个路由对应页面上的操作。只要看一下这些方法就知道可以传什么参数了,本质上来说,这里数据采集的方法也是和上面的一样,只不过提供了http接口,我们还是以cpu为例来看一下。
在这里插入图片描述

可以传递收集时间,默认30s 。这里收集的方法和一开始的例子是一样的。

和三方http库结合

按照上面的思路,和三方http结合就是将init方法中注册的路由注册到三方库的http中就好。这里以echo为例子

echo: https://echo.labstack.com/guide/

代码:

package main

import (
	"net/http"
	"net/http/pprof"

	"github.com/labstack/echo/v4"
)

func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!")
	})
	e.GET("/debug/pprof",echo.WrapHandler(http.HandlerFunc(pprof.Index)))
	e.GET("/debug/pprof", echo.WrapHandler(http.HandlerFunc(pprof.Index)))
	e.GET("/debug/pprof/allocs", echo.WrapHandler(http.HandlerFunc(pprof.Index)))
	e.GET("/debug/pprof/block", echo.WrapHandler(http.HandlerFunc(pprof.Index)))
	e.GET("/debug/pprof/goroutine", echo.WrapHandler(http.HandlerFunc(pprof.Index)))
	e.GET("/debug/pprof/heap", echo.WrapHandler(http.HandlerFunc(pprof.Index)))
	e.GET("/debug/pprof/mutex", echo.WrapHandler(http.HandlerFunc(pprof.Index)))
	e.GET("/debug/pprof/cmdline", echo.WrapHandler(http.HandlerFunc(pprof.Cmdline)))
	e.GET("/debug/pprof/profile", echo.WrapHandler(http.HandlerFunc(pprof.Profile)))
	e.GET("/debug/pprof/symbol", echo.WrapHandler(http.HandlerFunc(pprof.Symbol)))
	e.GET("/debug/pprof/trace", echo.WrapHandler(http.HandlerFunc(pprof.Trace)))
	e.Logger.Fatal(e.Start(":1323"))
}

在这里插入图片描述

echo中注册路由的方法是:

在这里插入图片描述

WrapHandler做了一层适配。

数据分析

  1. 查看heap profile

    go tool pprof http://localhost:8080/debug/pprof/heap
    
  2. 查看30s cpu profile

    go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
    
  3. 查看阻塞的goroutine

    go tool pprof http://localhost:6060/debug/pprof/block
    
  4. 查看mutexes

    go tool pprof http://localhost:6060/debug/pprof/mutex
    
  5. 查看trace

    curl -o trace.out http://localhost:6060/debug/pprof/trace?seconds=5
    go tool trace trace.out
    
  6. 查看pprof

    curl -o profile.out http://localhost:8080/debug/pprof/profile?debug=1
    go tool pprof   profile.out
    

引用下面文章:
https://geektutu.com/post/hpg-pprof.html

到这里结束了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/614008.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【AI】惠普暗夜精灵9安装Ubuntu20.04+nvidia驱动

1、关闭快速启动 NVIDIA驱动安装很是矫情,为了谨慎起见,还是禁用快速启动吧 在Win11下,进入控制面板–》硬件和声音–》电源选项–》更改电源按钮的功能 禁止“启用快速启动” 2、关闭设备加密 关闭设备加密,否则安装过程中会报:bitlocker加密需要解除 3、设置bios…

SpringMVC《学习笔记(21版尚硅谷)》

一、SpringMVC简介 1、什么是MVC MVC是一种软件架构的思想&#xff0c;将软件按照模型、视图、控制器来划分 M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;作用是处理数据 JavaBean分为两类&#xff1a; 一类称为实体类Bean&#xff1…

Form表单(antd-design组件库)简单使用以及单一检查规则

1.Form表单 高性能表单控件&#xff0c;自带数据域管理。包含数据录入、校验以及对应样式。 2.何时使用 用于创建一个实体或收集信息。 需要对输入的数据类型进行校验时。 组件代码来自&#xff1a; 表单 Form - Ant Design 3.本地验证前的准备 参考文章【react项目antd组件-de…

chatgpt赋能python:Python如何变大字体的SEO技巧

Python如何变大字体的SEO技巧 在网页设计和优化中&#xff0c;使用合适的字体和字体大小是至关重要的。对于使用Python编程的开发人员和网站管理员来说&#xff0c;如何使Pyhton代码中的字体变大是一个非常有用的技巧。在本文中&#xff0c;我们将介绍几种方法来增大Python代码…

C语言7:输入若干个学生的成绩,统计出平均成绩

在程序编辑区编写程序&#xff0c;给定程序功能是: 从键盘上输入若干个学生的成绩&#xff0c;统计出平均成绩&#xff0c;并输出低于平均分的学生成绩&#xff0c;用输入负数结束输入。 例如输入: 70 80 90 -1 输出: ave 80.00 --------OUTPUT----------- 70.0 程序有…

【茶话数据结构】查找最短路径——Dijkstra算法详解(保姆式详细图解,步步紧逼,保你学会)

&#x1f4af; 博客内容&#xff1a;【茶话数据结构】查找最短路径——Dijkstra算法详解 &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f989;所属专栏&#xff1a;数据结构笔记 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准前端&#xff0c;专注基础和实…

软考A计划-电子商务设计师-模拟试题卷一

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

chatgpt赋能python:Python抢票的绝招

Python 抢票的绝招 随着互联网技术的不断发展&#xff0c;越来越多的人开始享受网购的便利。但是&#xff0c;随着一些热门事件的到来&#xff0c;如演唱会、体育比赛等&#xff0c;大家面临同一个问题&#xff1a;如何抢到热门事件的门票&#xff1f;这时&#xff0c;Python …

Win10利用剪贴板多次粘贴

工作中需要经常复制粘贴图片&#xff0c;每次ctrl C, ctrl V来回切换效率很低 网上有很多剪贴板增强工具&#xff0c;但win10本身有增强版的功能 多次复制后&#xff0c;在需要粘贴的地方按下&#xff0c;Windows徽标 V&#xff0c;就会出现所有复制过的内容 需要哪个直接点…

2023/06/05 PM Day4 软件项目生存期和生命周期

视频参考地址&#xff1a; B站闫波软件项目管理视频学习. 视频资源&#xff1a;video P4-P6 本篇重点&#xff1a;项目生存期 简书日更计划同步记录&#x1f3c3;… 项目生命周期 软件项目生命周期 *项目生命周期的阶段 C概念/启动阶段&#xff1a;确立项目需求和目标D开发/计…

chatgpt赋能python:Python如何把数据存到字典

Python如何把数据存到字典 字典是Python中非常有用的数据类型之一&#xff0c;它允许您将值与唯一的键相关联&#xff0c;从而快速地查找、插入和删除数据。在这篇文章中&#xff0c;我们将介绍如何使用Python将数据存储到字典中。 什么是字典&#xff1f; 字典是Python中的…

[开发板]001瑞芯微3588s开发记录--装一个仿真环境

文章目录 前言1. 构建python环境2 模型转换 前言 我是一个开发板的新手&#xff0c;刚买了一个瑞芯微3588s的板子&#xff0c;目标是要学习嵌入式的开发&#xff0c;也就是说把深度学习的框架&#xff0c;跑到板子上。万丈高楼平地起步。先把仿真环境搭建起来。 仿真环境可以跑…

趣未来科技董事长黄婵娇:专注创新研发,把公司当做科研机构来运作!

身为研发型董事长&#xff0c;黄婵娇女士谈及“技术”&#xff0c;眼中总是透着由衷的自豪。她的办公室摆满了各类技术文件以及图纸&#xff0c;以身作则将技术研发基因带入公司核心运维&#xff0c;强势带动深圳市趣未来&#xff08;B2GO&#xff09;科技有限公司一步步成长为…

电赛备赛日记(一):K210与STM32串口通信

拖更了n久的备赛日记终于来啦&#xff0c;最近实现了关于K210图像识别并将所需数据&#xff08;即目标类别&#xff0c;目标在图像中的加权坐标&#xff09;其中&#xff0c;加权坐标指K210识别到的目标并框出的框的宽和高与框左上顶点的坐标加权&#xff0c;希望以此来判断目标…

海云捷讯杯 赛后总结 目标检测——缺陷检测(模型训练部分)

在这次比赛中&#xff0c;本人在队伍中主要负责模型训练部分&#xff0c;所以本文主要讲述如何使用PaddleDetection代码自定义数据集进行目标检测&#xff0c;欢迎大家纠错讨论哦&#xff0c;不胜荣幸~ 参考项目&#xff1a; SSDquexianjiance - 飞桨AI Studio (baidu.com) 感…

云上高校导航

2023042719 - 云上高校导航 中国大学生计算机设计大赛 广西赛区 软件应用与开发 - 移动应用开发&#xff08;非游戏类&#xff09; 三等奖 “云上高校导航”是一套基于小程序云开发的校园导航类系统开发方案。 该开发方案可供开发者进行二次开发&#xff0c;用于解决师生和访客…

MySQL数据库理论基础

数据库-理论基础 1.什么是数据库2.数据库管理系统(DBMS)3.数据库与文件系统的区别4.数据库的发展史5. 常见数据库5.1 关系型数据库5.2 非关系型数据库 6.MySQL简介7. MySQL的特性8.MySQL获取9.MySQL在企业中应用10.MySQL体系结构 1.什么是数据库 数据&#xff1a; 描述事物的符…

Linux 高级篇-定制自己的Linux 系统

Linux 高级篇-定制自己的Linux 系统 基本介绍 通过裁剪现有Linux 系统(CentOS7.6)&#xff0c;创建属于自己的min Linux 小系统&#xff0c;可以加深我们对linux 的理解。利用centos7.6&#xff0c;搭建一个小小linux 系统, 很有趣。 基本原理 启动流程介绍&#xff1a; 制…

LeetCode25. K 个一组翻转链表

给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改变节点内部的值…

操作系统之IO管理

目录 IO设备的概念和分类 IO控制器 IO控制方式 IO软件层次结构 IO应用程序接口和驱动程序接口 IO核心子系统 假脱机技术 IO设备的分配和回收 缓冲区管理 磁盘的结构 磁盘调度算法 磁盘的管理 固态硬盘 本文内容摘自&#xff1a;5.1_1_I-O设备的概念和分类_哔哩哔哩…