You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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,可以通过脚本手动转换单位:

  1. 先导出原始测试结果:
    go test -bench=. -count=1 > bench_results.txt
    
  2. 用简单的脚本(比如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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:25:48