Go基准测试中b StopTimer有什么用_Go测试流程解析
技术百科
P粉602998670
发布时间:2026-01-15
浏览: 次 b.StopTimer()用于临时排除初始化代码的耗时与内存分配统计,避免污染性能指标;必须在每次循环前停计时做初始化(如生成测试数据),再用b.ResetTimer()重置并开始测量。
b.StopTimer() 的作用是临时排
b.StartTimer() 或 b.ResetTimer() 之前,这段代码不算进最终的 ns/op 和 allocs/op”。
什么时候必须用 b.StopTimer()
当你需要在每次循环前做初始化(比如构建 map、预分配 slice、打开文件、生成测试数据),但又不想让这些“准备动作”污染性能指标时,就必须停掉计时器。
- 常见错误现象:基准测试结果远高于预期,且
allocs/op异常高——很可能是因为初始化逻辑被计入了统计 - 典型场景:测试一个排序函数,但每次都要先用
rand.Perm()生成随机数组;或测试 JSON 解析,但每次都在循环内json.Marshal()构造输入 - 不能只靠“写在外面”,因为
B.N是动态调整的,你无法预知要跑多少轮,初始化必须和循环对齐
b.StopTimer() 和 b.ResetTimer() 的关键区别
两者都用于控制统计范围,但语义和触发时机不同:
-
b.StopTimer():暂停统计,已累计的时间和分配仍保留;后续调用b.StartTimer()会继续累加(不是从零开始) -
b.ResetTimer():清空已统计的所有时间与分配,并立即重启计时——相当于“重置并开始新一阶段测量” - 多数情况下,初始化后应配对使用:
b.StopTimer()→ 初始化 →b.ResetTimer(),而不是b.StartTimer()
func BenchmarkSort(b *testing.B) {
// 预热/一次性 setup(可选)
data := make([]int, 1000)
b.ResetTimer() // ⚠️ 错!这里还没开始测,重置无效
for i := 0; i < b.N; i++ {
b.StopTimer()
// 每轮都需要的新输入
rand.Shuffle(len(data), func(i, j int) { data[i], data[j] = data[j], data[i] })
b.ResetTimer() // ✅ 正确:丢弃 shuffle 开销,从此刻重新计时
sort.Ints(data) // ← 这行才被统计
}}
不用 b.StopTimer() 会怎样?编译器还可能帮你“优化掉”
如果初始化逻辑没被隔离,不仅数据失真,还可能触发编译器优化,导致基准测试完全失效:
- 例如在循环里反复创建小字符串但没使用,Go 编译器可能直接删掉整段代码(尤其开启
-gcflags="-l"时) - 更隐蔽的问题:变量逃逸到堆上,导致
allocs/op虚高,你以为是算法问题,其实是测试写法问题 - 命令行验证技巧:加
-benchmem -gcflags="-m"看逃逸分析,再对比加/不加b.StopTimer()的allocs/op差异
真正容易被忽略的点是:b.StopTimer() 不是“暂停计时器”的字面意思,而是一次统计开关切换。它和 b.ReportAllocs()、b.SetBytes() 一样,属于“让框架知道你关心什么指标”的协作契约——你关得越准,结果越可信。
# 帮你
# 都在
# 是因为
# 当你
# 都要
# 计时器
# 什么时候
# 还没
# 还可能
# js
# json
# go
# 循环
# 堆
# 区别
# 字符串
# 算法
# map
# 变量逃逸
# 测试数据
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- 如何将文本文件中的竖排字符串转换为横排字符串
- Win11怎么开启窗口对齐助手_Windows11
- Win11怎么关闭系统声音_Win11系统提示音静
- Win11怎么开启HDR模式_Windows 11
- Windows如何设置登录时的欢迎屏幕背景?(锁屏
- Win10系统怎么查看端口状态_Windows10
- 如何使用Golang反射将map转换为struct
- Win11怎么清理C盘虚拟内存_Win11清理虚拟
- Win11怎么关闭搜索历史 Win11清除搜索框最
- Python随机数生成_random模块说明【指导
- Windows资源管理器总是卡顿或重启怎么办?(修
- 如何使用Golang操作指针变量_Golang解引
- Python变量绑定机制_引用模型解析【教程】
- Windows服务启动类型恢复方法_错误修改导致的
- 如何在Golang中处理云原生事件_使用Event
- Python邮件系统自动化教程_批量发送解析与模板
- Win11键盘快捷键大全_Windows 11常用
- PHP主流架构如何做单元测试_工具与流程【详解】
- Windows蓝屏错误0x0000001E怎么修复
- 如何使用Golang构建基础消息队列模拟_Gola
- Win11怎么开启游戏工具栏_Windows11
- 如何使用Golang读取日志文件_Golang b
- Windows 10怎么把任务栏放在屏幕上方_Wi
- Windows10电脑怎么设置文件权限_Win10
- Win11怎么开启专注模式_Windows11时钟
- Win11怎么关闭定位服务_保护Win11位置隐私
- php8.4匿名类怎么用_php8.4匿名类创建与
- Win11开机速度慢怎么优化_Win11系统启动加
- Python网络异常模拟_测试说明【指导】
- Linux如何挂载新硬盘_Linux磁盘分区格式化
- 如何在 Laravel 中通过嵌套关联关系进行 o
- 如何使用Golang开发基础文件下载功能_Gola
- 如何在 ACF 中正确更新嵌套多层的 Group
- 如何从 Go 的 map[string]inter
- Win10怎样设置闹钟贪睡时间 Win10闹钟贪睡
- 网站内页做seo排名怎么做?
- 如何在Golang中处理URL参数_Golang
- 如何使用Golang实现函数指针_函数变量与回调示
- c++怎么实现高并发下的无锁队列_c++ std:
- Windows10系统怎么查看运行时间_Win10
- Win11怎么设置默认浏览器Chrome_Wind
- Python与MongoDB NoSQL开发实战_
- C++中的constexpr和const有什么区别
- windows系统找不到无线网络怎么办_windo
- c++中如何求一个数的平方根_c++ sqrt函数
- php订单日志怎么记录发货_php记录订单发货操作
- Win10系统映像怎么恢复 Win10使用系统映像
- Windows10如何更改日期格式_Win10区域
- php8.4xdebug无法调试怎么办_php8.
- Windows10电脑怎么查看硬盘通电时间_Win

QQ客服