在Go基准测试中,allocs/op和B/op代表什么意思?

60

当我使用go test -v -bench=. -benchmem运行我的基准测试时,我看到以下结果。

f1     10000        120860 ns/op        2433 B/op         28 allocs/op
f2     10000        120288 ns/op        2288 B/op         26 allocs/op

根据我的理解:

  1. 10000是迭代次数for i := 0; i < b.N; i++ {
  2. XXX ns/op是完成一次迭代所需的近似时间。

但是即使阅读了文档,我仍然无法弄清楚B/opallocs/op的含义。


我猜allocs/op与垃圾回收和内存分配有关(越少越好)。

能否有人给出这些值的意义的简洁解释呢?知道它们为什么会上升,并采取哪些措施来减少它们将是很好的(我意识到这是测试特定的,但可能有一些通用提示适用于许多情况)。

2个回答

67

allocs/op表示每个操作(单次迭代)发生了多少个不同的内存分配。

B/op表示每个操作分配了多少字节的内存。


B/op是在堆栈帧中还是在堆中进行的分配?或者它是GO GC需要清理的内存量吗? - user3219492
4
有正式的文档来解释这些指标吗? - Ryan Lyu
“内存分配”是什么意思?这是否意味着“为变量设置一个值”? - Ryan Lyu
2
@RyanLv:不,这意味着内存被“分配”了,而不是被修改。给变量设置一个值只是修改预先分配的内存内容。 - Jonathan Hall
5
内存分配意味着从操作系统获取更多内存。这样做会减少您和系统中其他程序可用的内存。 - Inanc Gumus

2
快速查看“testing/benchmark.go”源代码,可以发现:
// AllocsPerOp returns the "allocs/op" metric,
// which is calculated as r.MemAllocs / r.N.
func (r BenchmarkResult) AllocsPerOp() int64

r.MemAllocs是什么意思?
type BenchmarkResult struct {
    MemAllocs uint64        // The total number of memory allocations.
    MemBytes  uint64        // The total number of bytes allocated.
    // ...
}

“总数”是如何累积的?
// file: testing/allocs.go

func AllocsPerRun(runs int, f func()) (avg float64) {
    // ...

    // Measure the starting statistics
    var memstats runtime.MemStats
    runtime.ReadMemStats(&memstats)
    mallocs := 0 - memstats.Mallocs

    // Run the function the specified number of times
    for i := 0; i < runs; i++ {
        f()
    }

    // Read the final statistics
    runtime.ReadMemStats(&memstats)
    mallocs += memstats.Mallocs

    // ...
    return float64(mallocs / uint64(runs))

所以现在我们知道,无论是runtime.Memstats.Mallocs,都是“alloc/ops”中的“alloc”。这是Memstate:
// file: runtime.mstats.go

type MemStats struct {
    // ...
    // Mallocs is the cumulative count of heap objects allocated.
    // The number of live objects is Mallocs - Frees.
    Mallocs uint64
    // ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接