0

0

如何在Golang中捕获错误并进行性能测试_Golang Benchmark错误处理实践

P粉602998670

P粉602998670

发布时间:2026-01-03 13:20:31

|

805人浏览过

|

来源于php中文网

原创

Go benchmark中禁用log.Fatal或panic,应使用b.Error()或b.Fatal()报告错误;setup阶段错误用b.Fatal()提前退出,循环内错误用b.Error()记录后continue,避免中断整个测试流程。

如何在golang中捕获错误并进行性能测试_golang benchmark错误处理实践

Go benchmark 中不能用 log.Fatalpanic 捕获错误

Go 的 testing.B 函数运行在受控环境中,一旦触发 panic 或调用 log.Fatal,整个基准测试会立即终止,且不报告任何结果(甚至不显示 BenchmarkXXX 已执行)。这不是“捕获错误”,而是让测试崩溃。

  • 正确做法是:所有错误必须显式检查并用 b.Error()b.Fatal() 报告(仅限失败时)
  • b.Fatal() 会标记该次 benchmark 失败并停止当前函数,但不会中断整个 go test -bench 流程
  • 若错误不影响性能逻辑(例如初始化失败),应在 BenchmarkXxx 开头处理,避免进入 b.ResetTimer() 后才出错

如何在 testing.B 中安全调用可能出错的函数

典型场景是被测函数返回 (result, error),比如 json.Marshalhttp.Post 模拟或数据库查询。直接忽略错误会导致结果不可信;用 if err != nil { panic(err) } 会让 benchmark 崩溃。

  • 把错误检查放在 b.ResetTimer() 之前 —— 如果 setup 阶段就失败,说明测试环境有问题,应提前退出
  • 如果错误发生在循环体内(即每次迭代都可能出错),必须判断并跳过本次迭代,或用 b.StopTimer() + b.StartTimer() 隔离错误处理开销
  • 不要在循环中调用 b.Fatal(),它会中断整个 benchmark 迭代;改用 b.Error() 记录后 continue
func BenchmarkJSONMarshal(b *testing.B) {
	data := map[string]int{"x": 1, "y": 2}
	// setup 阶段检查
	if _, err := json.Marshal(data); err != nil {
		b.Fatal("setup failed:", err)
	}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		out, err := json.Marshal(data)
		if err != nil {
			b.Error("marshal failed at iteration", i, ":", err)
			continue // 跳过本次,不计入计时
		}
		_ = out
	}
}

go test -bench 不显示错误详情?检查是否漏了 b.Error() 调用

默认情况下,benchmark 只输出耗时和内存分配数据,b.Error() 的内容不会自动打印,除非加上 -benchmem -v 参数。很多开发者以为“没报错”其实是错误被静默吞掉了。

堆友
堆友

Alibaba Design打造的设计师全成长周期服务平台,旨在成为设计师的好朋友

下载
  • 运行 benchmark 时务必加 -vgo test -bench=. -benchmem -v
  • b.Error()b.Fatal() 的输出只在失败时显示;如果 benchmark 成功完成(哪怕中间有 b.Error()),也不会中断,但错误信息仍会出现在终端
  • 注意区分:b.Error() 是记录错误但继续跑完所有 b.N 次;b.Fatal() 是立刻终止当前 benchmark 函数

错误处理本身会影响 benchmark 结果,需要隔离测量

真实代码里错误分支往往比正常路径慢得多(比如网络超时、磁盘 I/O 失败重试),直接把错误处理混进主循环会严重污染 ns/op 数据。你测的不是“成功路径性能”,而是“平均错误混合路径性能”。

  • 如需单独测错误路径性能,应写独立 benchmark,用构造的错误输入触发(例如传入非法 JSON 字节流给 json.Unmarshal
  • 避免在主 benchmark 循环中做条件分支判断错误类型;错误应是异常情况,不该出现在热路径
  • 如果业务逻辑强制要求每轮都 check error(比如 retry loop),那 benchmark 就该反映这个真实开销 —— 但要确保错误率可控(例如固定 1%),否则结果抖动太大
实际中最容易被忽略的是:**benchmark 的 b.N 是动态调整的,一旦某次迭代因错误导致耗时剧增,整个 b.N 可能被大幅下调,最终你看到的 ns/op 其实来自极少量样本,且无法复现**。务必先用小规模 -benchtime=10ms 验证逻辑稳定再拉长测试时间。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

177

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

225

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

336

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

206

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

189

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

191

2025.06.17

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

194

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.1万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号