golang基准测试示例分析

2023-08-16 20:22:51 浏览数 (1)

在Go的基准测试中,循环的次数(b.N)是由测试框架自动设置的,以尽可能多地运行测试,从而获取更准确的结果。我们不需要(也不能)手动设置这个数值。

这就是为什么我们在基准测试中通常会看到这样的循环:for i := 0; i < b.N; i 。测试框架会尝试不同的b.N值,看看在这个数量级下代码运行需要多少时间,然后基于这些结果计算出平均运行时间。

当我们运行基准测试的时候,可以使用-benchtime标志来指定运行基准测试的大概时间。例如,go test -bench=. -benchtime=10s会尽可能多地运行基准测试,直到大约10秒的时间。测试框架会在这个时间内尝试不同的b.N值。

请注意,-benchtime不是设置具体的运行次数,而是设置测试持续的时间。你不能直接设置运行基准测试的次数,这是由测试框架根据你的-benchtime值自动调整的。

代码语言:javascript复制
goos: linux
goarch: amd64
pkg: /pkg/adapter/cache/cachememdb
cpu: Intel(R) Xeon(R) Silver 4210 CPU @ 2.20GHz
BenchmarkCacheMemDB_Get-40        419230        2559 ns/op       304 B/op        12 allocs/op
PASS

基准测试结果的解读:

  • goos: linux:测试运行的操作系统是 Linux。
  • goarch: amd64:测试运行在 amd64 架构的硬件上。
  • pkg: /pkg/adapter/cache/cachememdb:基准测试的包路径。
  • cpu: Intel(R) Xeon(R) Silver 4210 CPU @ 2.20GHz:测试运行的 CPU 类型。
  • BenchmarkCacheMemDB_Get-40:这是你的基准测试函数,函数名是 "CacheMemDB_Get","40" 是并发的 goroutine 数量。这通常等于你的 CPU 核心数或者逻辑处理器的数量。
  • 419230:这个数字是基准测试运行的次数。测试框架自动选择这个数字,以便能够运行足够长的时间来产生有意义的结果。
  • 2559 ns/op:每次操作的平均纳秒数。这里的 "操作" 指的是调用一次 CacheMemDB_Get 函数。这个数字表示,平均来看,调用你的函数一次大约需要 2559 纳秒。
  • 304 B/op:这是每次操作的平均内存分配量。也就是说,每次调用 CacheMemDB_Get 函数平均分配了 304 字节的内存。
  • 12 allocs/op:这是每次操作的平均内存分配次数。这意味着,每次调用 CacheMemDB_Get 函数平均进行了 12 次内存分配。
  • PASS:表明所有的测试和基准测试都已成功通过。

这些信息可以帮助我们了解你的 CacheMemDB_Get 函数的性能特征,包括运行速度以及内存使用情况。

1毫秒(ms)等于1000000纳秒(ns)。因此,可以通过将纳秒数除以1000000来将其转换为毫秒数。

在这个例子中,2559纳秒(ns)可以转换为:

2559 ns ÷ 1,000,000 = 0.002559 ms

所以,2559纳秒约等于0.002559毫秒。

从基准测试的结果来看,函数的性能已经相当不错了。每次操作只需要2559纳秒(约0.002559毫秒),并且每次操作的平均内存分配量为304字节,平均进行了12次内存分配。在大多数应用场景下,这样的性能已经足够了。

然而,无论函数的性能如何,总是有优化的空间。你可以进一步考虑以下几个方面:

  1. 减少内存分配:函数每次调用平均分配了304字节的内存,并进行了12次内存分配。你可以检查你的函数,看看是否有不必要的内存分配,例如是否可以复用一些对象,以减少内存分配。
  2. 减少函数调用:你可以查看函数的代码,看是否有不必要的函数调用,或者是否可以合并一些函数调用。每个函数调用都有一些开销,如果能减少函数调用,可能能提高性能。
  3. 并发:函数的基准测试是在40个goroutine中运行的。你可以检查你的函数是否能够正确地并行运行,或者是否可以进一步提高并行性。例如,如果函数内部有一些可以并行的部分,但是现在是串行的,那么改为并行可能能提高性能。

请注意,这些都只是可能的优化方向,需要具体问题具体分析。另外,在进行任何优化之前,一定要明确优化的目标(例如,希望减少内存分配,或者减少运行时间),并使用基准测试来确认优化的效果。

0 人点赞