Go怎么做性能优化工具篇之基准测试
一、什么是基准测试(Benchmark)
在 Go 中,基准测试是通过创建以 Benchmark 开头的函数,并接收一个 *testing.B 类型的参数来实现的。testing.B 提供了控制基准测试执行的接口,比如设置测试执行的次数、记录每次执行的时间等。
每个基准测试函数都必须接受一个 *testing.B 类型的参数。函数体内通过 b.N来控制基准测试的执行次数,Go 会自动调整 b.N 的值,确保每次基准测试运行的时间足够长。
例如:
package mainimport ("testing"
)// 基准测试函数
func BenchmarkMyFunction(b *testing.B) {// 这里是测试的代码,每次循环 b.N 次for i := 0; i < b.N; i++ {// 被测试的函数或代码块_ = "hello"}
}
二、怎么进行基准测试
要运行基准测试,可以使用 go test 命令,指定 -bench 标志来启动基准测试。
go test -bench .
- bench .:表示运行当前目录下所有以 Benchmark 开头的函数。
- bench <pattern> :可以通过提供正则表达式来运行特定的基准测试,比如 go test -bench BenchmarkMyFunction 仅运行 BenchmarkMyFunction。
运行基准测试并报告内存分配
go test -bench . -benchmem
- benchmem:该标志会显示内存分配的详细信息,包括每次基准测试中分配了多少内存。
package mainimport ("testing""unsafe"
)func BenchmarkBytes2Str(b *testing.B) {aa := []byte("mclink")for n := 0; n < b.N; n++ {Bytes2Str(aa)}
}
func BenchmarkBytes2StrUnsafe(b *testing.B) {aa := []byte("mclink")for n := 0; n < b.N; n++ {Bytes2StrUnsafe(aa)}
}func Bytes2Str(b []byte) string {return string(b)
}func Bytes2StrUnsafe(b []byte) string {return *(*string)(unsafe.Pointer(&b))
}

#从左到右分别表示benchmark函数、运行次数、单次运行消耗的时间、单次运行内存分配的字节数和次数
BenchmarkBytes2Str-8 :基准测试的名称和 CPU 核心数量(这里 -8 表示在 8 核 CPU 上运行)。
317858601:测试函数执行了 20,000,000 次。
3.720 ns/op:每次执行 BenchmarkBytes2Str-8 的平均耗时为 3.72 纳秒。
0 B/op:每次测试没有内存分配。
0 allocs/op:每次测试没有进行内存分配。
三、复杂的基准测试
有时在基准测试中,某些初始化工作并不应该计入测试时间。可以使用 b.StartTimer() 和 b.StopTimer() 来控制计时开始和结束。
func BenchmarkWithStartStopTimer(b *testing.B) {// 1. 先进行一些初始化工作setup()// 2. 在基准测试前停止计时(这部分不会计入基准测试时间)b.StopTimer()// 3. 进行某些准备工作或其他代码,这部分不会计入基准测试时间time.Sleep(100 * time.Millisecond)// 4. 启动计时,开始计入基准测试时间b.StartTimer()// 5. 开始基准测试for i := 0; i < b.N; i++ {performWork()}// 6. 结束时停止计时b.StopTimer()
}
- b.StartTimer():开始计时。
- b.StopTimer():停止计时。
- b.ResetTimer():重置计时器,确保计时仅限于你关心的代码
你可以使用 b.ReportAllocs() 启用内存报告,来查看每次基准测试中分配了多少内存。
func BenchmarkAllocations(b *testing.B) {b.ReportAllocs() // 启用内存分配报告for i := 0; i < b.N; i++ {_ = make([]byte, 1024) // 模拟内存分配}
}

- 通过 -benchtime 设置基准测试时间
go test 命令支持 -benchtime 标志,可以控制基准测试的执行时长。例如,如果你想要让基准测试执行 2 秒钟:
go test -bench . -benchtime=2s
- 跳过普通单元测试,只运行基准测试
如果你只想运行基准测试,而跳过普通的单元测试,可以使用 -run=^$ 来过滤单元测试:
go test -bench . -run=^$
- 和pprof 混合双打
package mainimport ("fmt""testing""time""runtime/pprof""os"
)// 需要进行基准测试的函数
func performTask() {// 模拟耗时操作time.Sleep(100 * time.Millisecond)
}// 基准测试函数
func BenchmarkWithPprof(b *testing.B) {// 创建一个文件来保存 CPU 分析数据f, err := os.Create("cpu.pprof")if err != nil {b.Fatal("could not create CPU profile: ", err)}defer f.Close()// 启动 pprof,开始记录 CPU 使用情况if err := pprof.StartCPUProfile(f); err != nil {b.Fatal("could not start CPU profile: ", err)}defer pprof.StopCPUProfile()// 进行基准测试for i := 0; i < b.N; i++ {performTask()}
}// 运行基准测试的命令:go test -bench .
// 运行完之后会生成一个 cpu.pprof 文件,可以用 go tool pprof 查看分析数据。
如何使用 pprof 请看上一篇文章。
下一篇:Go的 Trace 工具~
相关文章:
Go怎么做性能优化工具篇之基准测试
一、什么是基准测试(Benchmark) 在 Go 中,基准测试是通过创建以 Benchmark 开头的函数,并接收一个 *testing.B 类型的参数来实现的。testing.B 提供了控制基准测试执行的接口,比如设置测试执行的次数、记录每次执行的…...
vue3国际化,主题切换
国际化 安装依赖 pnpm install i18n pnpm install vue-i18n main.js import { createApp } from vue import App from ./App.vue import { i18n } from /i18n/index; const app createApp(App) app.use(i18n); app.mount(#app) 根目录创建i18n文件夹,创建3个文件&…...
Linux Shell 脚本编程基础
打开kali,Xshell连接 一、 vim 1.sh 可利用 #! /bin/bash, #! /bin/dash ,#! bin/sh 这三种脚本解释器不论哪种,最终都是调用 dash 在1.sh内加入内容,尝试执行,./1.sh,但需要加权 或者,在不使用加权的情…...
vuex如何进行状态管理?
**Vuex:是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据共享。** (1) 如果是Vue2的环境,不能使用vuex4的版本,所以我们需要安装vuex3以下的版本安装。 创建项目:vue crea…...
嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
此项目是基于人脸识别的考勤系统开发,包括如下模块: 1、人脸识别考勤系统GUI界面设计,包括: (1)Qt环境(window环境/linux环境) ; (2)Qt工程创建分析; &am…...
通过阿里云 Milvus 与 PAI 搭建高效的检索增强对话系统
背景介绍 阿里云向量检索服务Milvus版(简称阿里云Milvus)是一款云上全托管服务,确保了了与开源Milvus的100%兼容性,并支持无缝迁移。在开源版本的基础上增强了可扩展性,能提供大规模 AI 向量数据的相似性检索服务。相…...
评估大语言模型在药物基因组学问答任务中的表现:PGxQA
这篇文献主要介绍了一个名为PGxQA的资源,用于评估大语言模型(LLM)在药物基因组学问答任务中的表现。 研究背景 药物基因组学(Pharmacogenomics, PGx)是精准医学中最有前景的领域之一,通过基因指导的治疗…...
在本地和远程转储域控制器哈希
更多内网知识课前往无问社区查看http://www.wwlib.cn 无凭据 - ntdsutil 如果您没有凭据,但有权访问 DC,则可以使用 lolbin ntdsutil.exe转储 ntds.dit: powershell "ntdsutil.exe ac i ntds ifm create full c:\temp q q" 我们…...
基于SSM+Vue的心理咨询问诊系统+LW示例参考
1.项目介绍 项目角色:管理员、患者(普通用户)、医师项目模块:医生管理、患者管理、科室管理、咨询管理、预约管理、急救知识、患者病历等测试环境:idea2024、tomcat8.5、maven3、jdk8、nodeV14.16.1、mysql5.7技术栈&…...
基于TMS320X281X/F28335的DSP入门到精通01_如何开始DSP的学习与开发
本部分开始基于《手把手教你学DSP—基于TMS320X281X》,《手把手教你DSP基于MS320F28335 》、《TMS320X281x DSP原理及C程序开发》,另外结合B站视频进行DSP嵌入式的学习。 《手把手教你学DSP—基于TMS320X281X》介绍的相对更为基础和详细,《手…...
Java爬虫获取1688 item_search_img接口详细解析
概述 1688作为中国领先的B2B电商平台,提供了丰富的API接口供开发者获取商品信息。item_search_img接口允许通过图片搜索商品,这对于需要基于图片进行商品查找的应用场景非常有用。本文将详细介绍如何使用Java爬虫技术获取1688的item_search_img接口数据…...
Java 连接 FTP 服务器全解析
Java 连接 FTP 服务器全解析 一、引言 在许多企业级应用和数据处理场景中,与 FTP 服务器进行交互是一项常见且重要的任务。Java 提供了强大的工具和库来实现与 FTP 服务器的连接、文件传输、目录操作等功能。本文将详细介绍如何使用 Java 连接 FTP 服务器…...
字节跳动C++面试题及参考答案(下)
说说B 树 b + 树 B 树: B 树是一种平衡的多路查找树,它的设计目的是为了减少磁盘 I/O 操作,适用于存储大量的数据并进行高效的查找、插入和删除操作。B 树的节点可以有多个子节点(通常称为多路),每个节点包含多个关键字,关键字之间是有序的。 B 树的结构特点包括:根节点…...
Rabbit MQ知识总结
1.什么是Rabbit MQ? Rabbit MQ是一个开源的消息代理软件,它实现了高级消息队列协议(AMQP); 基本概念 消息:消息是在应用程序之间传递的数据单元。可以是简单的文本信息,可以是复杂的对象。队列:队列是消息的容器&am…...
未来将要被淘汰的编程语言
COBOL - 这是一种非常古老的语言,主要用于大型企业系统和政府机构。随着老一代IT工作人员的退休,COBOL程序员变得越来越少。Fortran - 最初用于科学和工程计算,Fortran在特定领域仍然有其应用,但随着更现代的语言(如Py…...
GO环境安装和配置
安装go环境 wget https://go.dev/dl/go1.22.4.linux-amd64.tar.gz -P /usr/local或者去官网下载安装包 tar -xzf go1.23.4.linux-amd64.tar.gz sudo mv go /usr/local export GOROOT/usr/local/go export GOPATH$HOME/go export PATH$PATH:/usr/local/go/bin source ~/.bashr…...
面试题整理(四)
1.Max transition,leakage优化,hold time ,setup time violation修复的顺序是? 答:先把max transition修复掉,如果max transition有violation,意味着其超出了查找表范围之外,所以计算得到的delay都不是很准的。 其次是把setup修复了,因为setup相对来说,需要减少cell…...
mathtype中如何在公式和序号之间加点
1,右编号插入公式 2,打开样式面板(ctrlshiftalts) 3,选中MTDisplayEquation样式,右击修改 4,点击格式,弹出下拉列表,点击制表位 5,先选中34.67字符&#…...
【电源专题】电源芯片的PG(Power Good)管脚是什么?
在看电源芯片规格书时,你会发现有一些电源芯片有PG管脚。如下ti.com.cn/product/cn/tps56637?qgpn=tps56637规格书所示: 对应的描述是:Open Drain Power Good Indicator, it is asserted low if output voltage is out of PG threshold due to over-voltage, under…...
C/C++圣诞树
系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
