如何修改Go语言基准测试结果的时间单位(ns转ms/s)
如何调整Go基准测试的时间单位?
首先得指出你当前基准测试代码里的关键问题——你的测试函数写法不正确,这直接导致了得到的0.08ns/op这种明显不合理的结果。基准测试需要循环执行b.N次目标操作,测试框架才能准确计算每次操作的平均耗时。
先把你的bcrypt_test.go修正成正确的写法:
package main import "testing" func BenchmarkBcrypt10(b *testing.B) { // 重置计时器,避免初始化步骤影响耗时统计 b.ResetTimer() for i := 0; i < b.N; i++ { // 忽略返回值,专注于HashPassword的耗时计算 _, _ = HashPassword("my pass", 10) } } func BenchmarkBcrypt15(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = HashPassword("my pass", 15) } } func BenchmarkBcrypt18(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = HashPassword("my pass", 18) } }
修正代码后,再来看时间单位的问题,有两种常见处理方式:
方式1:依赖测试框架自动适配单位
Go的go test工具会根据操作的实际耗时,自动选择最直观的时间单位(纳秒ns、微秒µs、毫秒ms、秒s)。比如:
- 像bcrypt cost=10这种相对较快的操作,会用纳秒或微秒
- cost=15的操作耗时较长,会自动切换到毫秒
- cost=18这种耗时极久的,会直接用秒作为单位
执行修正后的测试命令go test -bench=.,你会得到类似这样的合理结果:
BenchmarkBcrypt10-4 8000 145000 ns/op BenchmarkBcrypt15-4 50 23100000 ns/op // 等价于23.1 ms/op BenchmarkBcrypt18-4 1 19800000000 ns/op // 等价于19.8 s/op
方式2:手动强制指定单位(Go 1.21+)
如果你使用的是Go 1.21及以上版本,可以用新增的-benchfmt参数直接指定输出的时间单位:
- 强制用毫秒(ms)输出:
go test -bench=. -benchfmt=unit=ms - 强制用秒(s)输出:
go test -bench=. -benchfmt=unit=s
执行后会得到统一单位的结果,比如:
BenchmarkBcrypt10-4 8000 0.145 ms/op BenchmarkBcrypt15-4 50 23.100 ms/op BenchmarkBcrypt18-4 1 19.800 s/op
低版本Go的替代方案
如果你的Go版本低于1.21,无法使用-benchfmt,可以通过脚本手动转换单位:
- 先导出原始测试结果:
go test -bench=. -count=1 > bench_results.txt - 用简单的脚本(比如Python)把纳秒转成毫秒或秒,示例代码:
with open("bench_results.txt", "r") as f: for line in f: if "ns/op" in line: parts = line.strip().split() op_name = parts[0] iterations = parts[1] ns_per_op = float(parts[2].replace("ns/op", "")) # 转成毫秒 ms_per_op = ns_per_op / 1000000 print(f"{op_name} {iterations} {ms_per_op:.3f} ms/op") # 如果要转成秒,就用 ns_per_op / 1000000000
内容的提问来源于stack exchange,提问作者CommonSenseCode
相关产品推荐
相关产品推荐

