当前位置: 首页 > news >正文

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怎么做性能优化工具篇之基准测试

一、什么是基准测试&#xff08;Benchmark&#xff09; 在 Go 中&#xff0c;基准测试是通过创建以 Benchmark 开头的函数&#xff0c;并接收一个 *testing.B 类型的参数来实现的。testing.B 提供了控制基准测试执行的接口&#xff0c;比如设置测试执行的次数、记录每次执行的…...

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文件夹&#xff0c;创建3个文件&…...

Linux Shell 脚本编程基础

打开kali&#xff0c;Xshell连接 一、 vim 1.sh 可利用 #! /bin/bash, #! /bin/dash ,#! bin/sh 这三种脚本解释器不论哪种&#xff0c;最终都是调用 dash 在1.sh内加入内容&#xff0c;尝试执行&#xff0c;./1.sh&#xff0c;但需要加权 或者&#xff0c;在不使用加权的情…...

vuex如何进行状态管理?

**Vuex&#xff1a;是实现组件全局状态&#xff08;数据&#xff09;管理的一种机制&#xff0c;可以方便的实现组件之间数据共享。** (1) 如果是Vue2的环境&#xff0c;不能使用vuex4的版本&#xff0c;所以我们需要安装vuex3以下的版本安装。 创建项目&#xff1a;vue crea…...

嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目

此项目是基于人脸识别的考勤系统开发&#xff0c;包括如下模块&#xff1a; 1、人脸识别考勤系统GUI界面设计&#xff0c;包括&#xff1a; &#xff08;1&#xff09;Qt环境(window环境/linux环境) &#xff1b; &#xff08;2&#xff09;Qt工程创建分析&#xff1b; &am…...

通过阿里云 Milvus 与 PAI 搭建高效的检索增强对话系统

背景介绍 阿里云向量检索服务Milvus版&#xff08;简称阿里云Milvus&#xff09;是一款云上全托管服务&#xff0c;确保了了与开源Milvus的100%兼容性&#xff0c;并支持无缝迁移。在开源版本的基础上增强了可扩展性&#xff0c;能提供大规模 AI 向量数据的相似性检索服务。相…...

评估大语言模型在药物基因组学问答任务中的表现:PGxQA

​这篇文献主要介绍了一个名为PGxQA的资源&#xff0c;用于评估大语言模型&#xff08;LLM&#xff09;在药物基因组学问答任务中的表现。 研究背景 药物基因组学&#xff08;Pharmacogenomics, PGx&#xff09;是精准医学中最有前景的领域之一&#xff0c;通过基因指导的治疗…...

在本地和远程转储域控制器哈希

更多内网知识课前往无问社区查看http://www.wwlib.cn 无凭据 - ntdsutil 如果您没有凭据&#xff0c;但有权访问 DC&#xff0c;则可以使用 lolbin ntdsutil.exe转储 ntds.dit&#xff1a; powershell "ntdsutil.exe ac i ntds ifm create full c:\temp q q" 我们…...

基于SSM+Vue的心理咨询问诊系统+LW示例参考

1.项目介绍 项目角色&#xff1a;管理员、患者&#xff08;普通用户&#xff09;、医师项目模块&#xff1a;医生管理、患者管理、科室管理、咨询管理、预约管理、急救知识、患者病历等测试环境&#xff1a;idea2024、tomcat8.5、maven3、jdk8、nodeV14.16.1、mysql5.7技术栈&…...

基于TMS320X281X/F28335的DSP入门到精通01_如何开始DSP的学习与开发

本部分开始基于《手把手教你学DSP—基于TMS320X281X》&#xff0c;《手把手教你DSP基于MS320F28335 》、《TMS320X281x DSP原理及C程序开发》&#xff0c;另外结合B站视频进行DSP嵌入式的学习。 《手把手教你学DSP—基于TMS320X281X》介绍的相对更为基础和详细&#xff0c;《手…...

Java爬虫获取1688 item_search_img接口详细解析

概述 1688作为中国领先的B2B电商平台&#xff0c;提供了丰富的API接口供开发者获取商品信息。item_search_img接口允许通过图片搜索商品&#xff0c;这对于需要基于图片进行商品查找的应用场景非常有用。本文将详细介绍如何使用Java爬虫技术获取1688的item_search_img接口数据…...

Java 连接 FTP 服务器全解析

Java 连接 FTP 服务器全解析 一、引言 在许多企业级应用和数据处理场景中&#xff0c;与 FTP 服务器进行交互是一项常见且重要的任务。Java 提供了强大的工具和库来实现与 FTP 服务器的连接、文件传输、目录操作等功能。本文将详细介绍如何使用 Java 连接 FTP 服务器&#xf…...

字节跳动C++面试题及参考答案(下)

说说B 树 b + 树 B 树: B 树是一种平衡的多路查找树,它的设计目的是为了减少磁盘 I/O 操作,适用于存储大量的数据并进行高效的查找、插入和删除操作。B 树的节点可以有多个子节点(通常称为多路),每个节点包含多个关键字,关键字之间是有序的。 B 树的结构特点包括:根节点…...

Rabbit MQ知识总结

1.什么是Rabbit MQ&#xff1f; Rabbit MQ是一个开源的消息代理软件&#xff0c;它实现了高级消息队列协议(AMQP); 基本概念 消息&#xff1a;消息是在应用程序之间传递的数据单元。可以是简单的文本信息&#xff0c;可以是复杂的对象。队列&#xff1a;队列是消息的容器&am…...

未来将要被淘汰的编程语言

COBOL - 这是一种非常古老的语言&#xff0c;主要用于大型企业系统和政府机构。随着老一代IT工作人员的退休&#xff0c;COBOL程序员变得越来越少。Fortran - 最初用于科学和工程计算&#xff0c;Fortran在特定领域仍然有其应用&#xff0c;但随着更现代的语言&#xff08;如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&#xff0c;右编号插入公式 2&#xff0c;打开样式面板&#xff08;ctrlshiftalts&#xff09; 3&#xff0c;选中MTDisplayEquation样式&#xff0c;右击修改 4&#xff0c;点击格式&#xff0c;弹出下拉列表&#xff0c;点击制表位 5&#xff0c;先选中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…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

Golang——6、指针和结构体

指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...