登录
首页 >  Golang >  Go问答

输出的 benchmem

来源:stackoverflow

时间:2024-03-03 11:30:26 451浏览 收藏

亲爱的编程学习爱好者,如果你点开了这篇文章,说明你对《输出的 benchmem》很感兴趣。本篇文章就来给大家详细解析一下,主要介绍一下,希望所有认真读完的童鞋们,都有实质性的提高。

问题内容

使用内存分析器运行基准测试时,我看到以下输出

SomeFunc             100      17768876 ns/op         111 B/op          0 allocs/op

我不明白输出 - 0 allocs/op 但分配了 111 b?知道这意味着什么吗?我的函数是否在堆上分配内存?


解决方案


基准测试结果收集在 testing.BenchmarkResult 类型的值中:

type benchmarkresult struct {
        n         int           // the number of iterations.
        t         time.duration // the total time taken.
        bytes     int64         // bytes processed in one iteration.
        memallocs uint64        // the total number of memory allocations; added in go 1.1
        membytes  uint64        // the total number of bytes allocated; added in go 1.1
}

您看到的已分配内存和每个操作的分配值由 BencharkResult.AllocedBytesPerOp()BenchmarkResult.AllocsPerOp() 返回。它们记录了返回值是:

所以结果是整数除法。这意味着,如果基准函数在不同的调用中执行不同数量的分配,结果可能不是整数,而是丢弃小数部分(这就是整数除法的工作原理)。

因此,如果函数平均执行少于 1 次分配,您将看到 0 allocs/op,但如果每次调用的平均值至少为 1 个字节,则分配的内存可能大于 0。

让我们看一个例子:

var (
    counter   int
    falsecond bool // always false at runtime
)

func avghalfallocs() {
    counter++
    if counter%2 == 0 {
        return
    }
    buf := make([]byte, 128)
    if falsecond {
        fmt.println(buf)
    }
}

func avgoneandhalfallocs() {
    for i := 0; i < 3; i++ {
        avghalfallocs()
    }
}

此处 avghalfallocs() 平均每次调用执行一半分配,它通过从一半调用返回而不分配任何内容,并在另一半调用中执行 1 次分配来实现。

avgoneandhalfallocs() 平均每次调用执行 1.5 次分配,因为它调用 avghalfallocs() 3 次。

falsecond 变量和 fmt.println() 调用的目的只是让编译器不会优化我们的分配,但 fmt.println() 永远不会被调用,因此它不会干扰分配。

对上述两个函数进行基准测试,如下所示:

func benchmarkavghalfallocs(b *testing.b) {
    for i := 0; i < b.n; i++ {
        avghalfallocs()
    }
}

func benchmarkavgoneandhalfallocs(b *testing.b) {
    for i := 0; i < b.n; i++ {
        avgoneandhalfallocs()
    }
}

结果是:

BenchmarkAvgHalfAllocs-4          50000000    29.2 ns/op    64 B/op   0 allocs/op
BenchmarkAvgOneAndHalfAllocs-4    20000000    92.0 ns/op   192 B/op   1 allocs/op

如您所见,在 avghalfallocs() 的情况下,每次调用 0.5 个分配被截断为 0,在 avgoneandhalfallocs() 的情况下,1.5 个分配被截断为 1。

avghalfallocs() 的平均分配内存为 0.5 * 128 字节 = 64 字节。

avgoneandhalfallocs() 的平均分配内存为 1.5 * 128 字节 = 192 字节。

今天关于《输出的 benchmem》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>