Go怎么做性能优化工具篇之基准测试

news2024/12/24 6:55:21

一、什么是基准测试(Benchmark)

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

每个基准测试函数都必须接受一个 *testing.B 类型的参数。函数体内通过 b.N来控制基准测试的执行次数,Go 会自动调整 b.N 的值,确保每次基准测试运行的时间足够长。

例如:

package main

import (
	"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 main

import (
	"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 main

import (
	"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 工具~

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

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

相关文章

【贪吃蛇小游戏 - JavaIDEA】基于Java实现的贪吃蛇小游戏导入IDEA教程

有问题请留言或私信 步骤 下载项目源码&#xff1a;项目源码 解压项目源码到本地 打开IDEA 左上角&#xff1a;文件 → 新建 → 来自现有源代码的项目 找到解压在本地的项目源代码文件&#xff0c;点击确定 选择“从现有项目创建项目”。点击“下一步” 点击下一步&a…

LabVIEW手机屏幕耐冲击测试

开发了一个基于LabVIEW的智能手机屏幕耐冲击测试系统。系统利用LabVIEW软件与高精度传感器&#xff0c;对手机屏幕进行落球冲击试验&#xff0c;以测定其耐冲击性能。这项技术不仅提高了测试的精度和效率&#xff0c;而且对智能手机屏幕的质量控制和改进提供了科学依据。 项目背…

Python + 深度学习从 0 到 1(01 / 99)

希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【深度学习从 0 到 1】谢谢你的支持&#xff01; ⭐ 深度学习之前&#xff1a;机器学习简史 什么要了解…

FPGA学习(基于小梅哥Xilinx FPGA)学习笔记

相关资源网站&#xff08;小梅哥FPGA&#xff09; https://www.corecourse.cn/forum.php?modviewthread&tid27978 https://www.corecourse.cn/forum.php?modviewthread&tid28730 本篇文章使用的开发板为&#xff1a; 小梅哥 Xilinx FPGA 型号&#xff1a;XC7A35T 芯…

网安瞭望台第17期:Rockstar 2FA 故障催生 FlowerStorm 钓鱼即服务扩张现象剖析

国内外要闻 Rockstar 2FA 故障催生 FlowerStorm 钓鱼即服务扩张现象剖析 在网络安全的复杂战场中&#xff0c;近期出现了一个值得关注的动态&#xff1a;名为 Rockstar 2FA 的钓鱼即服务&#xff08;PhaaS&#xff09;工具包遭遇变故&#xff0c;意外推动了另一个新生服务 Flo…

aws(学习笔记第十九课) 使用ECS和Fargate进行容器开发

aws(学习笔记第十九课) 使用ECS和Fargate进行容器开发 学习内容&#xff1a; 使用本地EC2中部署docker应用使用ECS的EC2模式进行容器开发使用ECS的Fargate模式进行容器开发 1. 使用本地EC2中部署docker应用 docker整体 这里展示了docker的整体流程。 开发阶段 编写dockerfile…

【Python 图片下载器】一款专门为爬虫制作的图片下载器,多线程下载,速度快,支持续传/图片缩放/图片压缩/图片转换

文章日期&#xff1a;2024.12.23 使用工具&#xff1a;Python 本章知识&#xff1a;制作一款图片下载器_DOS窗口&#xff08;爬虫专用&#xff09; 文章难度&#xff1a;低等&#xff08;没难度&#xff09; 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要…

关于博客系统的自动化功能测试报告

1.项目背景 基于 SSM 的个人博客系统测试 博客系统采用前后端分离的方法来实现&#xff0c;同时使用了数据库来存储相关的数据&#xff0c;前端主要有四个页面构成:登录页、列表页、详情页以及编辑页&#xff0c;模拟实现了个人博客列表页面&#xff0c;其结合后端实现了以下的…

计算机的错误计算(一百八十九)

摘要 用大模型计算 tan(12.345) . 自变量取弧度。结果保留10位有效数字。不同于前面两节的大模型&#xff0c;本节调用了新的两个大模型。然而&#xff0c;很遗憾&#xff0c;它们给出的答案似乎仍然是“匹配”出来的&#xff0c;不是计算出来的。当然&#xff0c;均是错误的。…

IP地址数据信息和爬虫拦截的关联

IP地址数据信息和爬虫拦截的关联主要涉及到两方面的内容&#xff0c;也就是数据信息和爬虫。IP 地址数据信息的内容丰富&#xff0c;包括所属地域、所属网络运营商、访问时间序列、访问频率等。 从IP地址信息中可以窥见多样的数据&#xff0c;那么我们应该怎么利用IP地址信息来…

springboot+logback学习文档

目录 1、前提说明2、引入依赖、将logback配置文件打到classes下2.1、引入依赖2.2、将logback配置文件打到classes下 3、使用说明3.1、配置文件名称和位置3.2、常规用法3.2.1、property标签&#xff08;普通变量&#xff09;3.2.2、springProperty标签&#xff08;spring变量&am…

Laya ios接入goole广告,开始接入 2

开始使用 | iOS | Google for Developers 谷歌广告的官网&#xff0c;需要搭梯子&#xff0c;API你说详细吧&#xff0c;也就那样&#xff0c;主要是没接过 一步步来吧 0.laya导包 前端出包原生 screenorientation 全部 portrait&#xff0c;我这个是竖屏的 注意这个&a…

详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用

目录 详解js柯里化原理及用法&#xff0c;探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用 一、什么是柯里化&#xff1f; 1、原理解析 2、一个直观的例子 二、如何实现柯里化&#xff1f; 1、底层实现 2、工作原理解析 3…

EDGE浏览器每次关闭时再次打开保存的密码就消失如何解决

文章目录 EDGE浏览器每次重启的时候保存的密码都消失如何解决&#xff1f; 打开EDGE浏览器点击三个点 点击设置 点击隐私、搜索和服务 找到选择每次关闭浏览器时要清除的内容 将开启的关闭即可

数据流图和流程图的区别

在结构化建模中&#xff0c;数据流图和流程图都是非常重要的工具&#xff0c;它们为开发人员提供了强大的手段来分析和设计系统。尽管两者在表面上看起来有些相似&#xff0c;但它们在功能、用途和表达方式上存在显著的区别。本文将详细探讨数据流图和流程图的区别&#xff0c;…

云计算中的容器技术(如Docker)是什么?

今天想和大家聊聊容器技术&#xff0c;特别是Docker这个大家可能经常听到的名词。记得我刚接触容器技术时也觉得挺抽象的&#xff0c;让我用简单的比喻来说明吧。 想象一下你在搬家。传统方式是把所有家具、电器分散装车&#xff0c;到了新家还要重新组装、调试。这就像我们以…

《Opencv》基础操作详解(2)

接上篇&#xff1a;《Opencv》基础操作详解&#xff08;1&#xff09;-CSDN博客 目录 Opencv基础操作 11、B、G、R颜色通道提取 12、显示单个通道颜色 13、 合并颜色通道 14、图像添加马赛克 15、图片区域替换 16、图片的缩放&#xff08;常用&#xff09; 17、图像运算…

STM32——“SPI Flash”

引入 在给单片机写程序的时候&#xff0c;有时会用到显示屏&#xff0c;就拿市面上的0.96寸单色显示器来说&#xff0c;一张全屏的图片就占用8x1281024个字节&#xff0c;即1kb的空间&#xff0c;这对于单片机来说确实有点奢侈&#xff0c;于是我买了一个8Mb的SPI Flash&#x…

深入浅出:AWT的基本组件及其应用

目录 前言 1. AWT简介 2. AWT基本组件 2.1 Button&#xff1a;按钮 2.2 Label&#xff1a;标签 ​编辑 2.3 TextField&#xff1a;文本框 2.4 Checkbox&#xff1a;复选框 2.5 Choice&#xff1a;下拉菜单 2.6 List&#xff1a;列表 综合案例 注意 3. AWT事件处理 …

Flutter组件————PageView

PageView 可以创建滑动页面效果的widget&#xff0c;它允许用户通过水平或垂直滑动手势在多个子页面&#xff08;child widgets&#xff09;之间切换。每个子页面通常占据屏幕的全部空间。 参数 参数名类型描述childrenList<Widget>包含在 PageView 中的所有子部件&am…