Go 编程 | 连载 34 - Benchmark 基准测试

简介: Go 编程 | 连载 34 - Benchmark 基准测试

一、基准测试 Benchmark

Go 编程 | 连载 33 - UnitTest 单元测试 中实现了 Go 的单元测试用例,单元测试的一般形式为:

TestXxx(t *testing.T)
复制代码

除此之外 Go 的 testing 标准库还包含一个强大的基准测试,基准测试可以反复的运行函数,从而建立基准,并且无须执行运行次数,因为框架会通过调整次数来获得可靠的数据集,基准测试结束后将获得一个报告,该保函中包含了运行次数以及运行一次消耗的时间,单位为 ns。

基准测试函数的命名方式为 BenchmarkXxx 并且要求传入一个 *testing.B 类型。

BenchmarkXxx(b *testing.B) 
复制代码

新建一个 fib.go 文件,增加一个函数 Fib

func Fib(n int) int {
   if n < 2 {
      return n
   }
   return Fib(n-1) + Fib(n-2)
}
复制代码

新增一个测试文件 benchmark_fib_test.go,增加测试函数 BenchmarkFib

func BenchmarkFib(b *testing.B) {
   for n := 0; n < b.N; n++ {
      Fib(20)
   }
}
复制代码

执行该测试文件,输出内容如下:

goos: darwin
goarch: amd64
pkg: go-advanced/10-test
cpu: Intel(R) Core(TM) i7-8557U CPU @ 1.70GHz
BenchmarkFib
BenchmarkFib-8       26546       45176 ns/op
PASS
复制代码

使用 IDEA 运行基准测试时,要注意基准测试用例的名字一定要是 BenchmarkXxx 形式,否则会报错,将函数名改为 FibTest,再次执行测试。

4bbb1ae7179643a7a1fafdcf15b1cb65_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

基准测试函数的名字为 BenchmarkXxx 时会自动使用 go bench 执行测试。

b561a8049fd94e32bff44c7374b21920_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

基准测试可以通过程序来确定完成特定任务时性能最佳的方式是哪一种。

新建一个 tango.go 文件,定义三个函数实现拼接字符串。

func StringFromAssignment(x int) string {
   var s string
   for i := 0; i < x; i++ {
      s += "tango"
   }
   return s
}
func StringFromAppendJoin(x int) string {
   s := []string{}
   for i := 0; i < x; i++ {
      s = append(s, "tango")
   }
   return strings.Join(s, "")
}
func StringFromBuffer(x int) string {
   var buffer bytes.Buffer
   for i := 0; i < x; i++ {
      buffer.WriteString("tango")
   }
   return buffer.String()
}
复制代码

同级目录下新建一个 tango_benchmark_test.go 文件,定义三个函数的基准测试函数。

func BenchmarkStringFromAssignment(b *testing.B) {
   for i := 0; i < b.N; i++ {
      StringFromAssignment(100)
   }
}
func BenchmarkStringFromAppendJoin(b *testing.B) {
   for i := 0; i < b.N; i++ {
      StringFromAppendJoin(100)
   }
}
func BenchmarkStringFromBuffer(b *testing.B) {
   for i := 0; i < b.N; i++ {
      StringFromBuffer(100)
   }
}
复制代码

执行基准测试,输出结果如下

goos: darwin
goarch: amd64
pkg: go-advanced/10-test
cpu: Intel(R) Core(TM) i7-8557U CPU @ 1.70GHz
BenchmarkStringFromAssignment
BenchmarkStringFromAssignment-8       148418        7382 ns/op
BenchmarkStringFromAppendJoin
BenchmarkStringFromAppendJoin-8       555007        2001 ns/op
BenchmarkStringFromBuffer
BenchmarkStringFromBuffer-8          1422670         818.5 ns/op
PASS
复制代码

可以看出使用 StringFromBuffer 函数拼接字符串耗时最短,效率最高。

二、testing.B 类型

*testing.B 类型是基准测试函数的入参,类似单元测试中的 *testing.T,也适用于管理测试的行为。

*testing.B*testing.T 类型一样都组合了 common 结构体,所有也都拥有 FailNowSkipNowSkipf 等方法来结束测试并输出格式化错误信息。

f790b62efac745bd98cf3c1878add6bf_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

*testing.B 类型可以用于管理基准测试的计时行为,有三个方法用于计时:

  • StartTimer:开始对测试进行计时。该方法会在基准测试开始时自动被调用,也可以在调用 StopTimer 之后恢复计时;
  • StopTimer:停止对测试进行计时。当需要执行一些复杂的初始化操作,并且不想对这些操作进行测量时,就可以使用这个方法来暂时地停止计时;
  • ResetTimer:对已经逝去的基准测试时间以及内存分配计数器进行清零。对于正在运行中的计时器,这个方法不会产生任何效果。

efa721f8967a4bf6a58f1f650181d8dd_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

基准测试还可以统计内存消耗以及指定运行时间等,只需要在命令行运行时添加相应的参数即可。


相关文章
|
7天前
|
人工智能 自然语言处理 前端开发
CodeArena:在线 LLM 编程竞技场!用于测试不同开源 LLM 的编程能力,实时更新排行榜
CodeArena 是一个在线平台,用于测试和比较不同大型语言模型(LLM)的编程能力。通过实时显示多个 LLM 的代码生成过程和结果,帮助开发者选择适合的 LLM,并推动 LLM 技术的发展。
37 7
CodeArena:在线 LLM 编程竞技场!用于测试不同开源 LLM 的编程能力,实时更新排行榜
|
29天前
|
数据库连接 Go 数据库
Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性
本文探讨了Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性;防御编程则强调在编码时考虑各种错误情况,确保程序健壮性。文章详细介绍了这两种技术在Go语言中的实现方法及其重要性,旨在提升软件质量和可靠性。
29 1
|
1月前
|
数据采集 监控 Java
go语言编程学习
【11月更文挑战第3天】
41 7
|
1月前
|
测试技术 Go
go语言中测试工具
【10月更文挑战第22天】
31 4
|
1月前
|
Unix Linux Go
go进阶编程:Golang中的文件与文件夹操作指南
本文详细介绍了Golang中文件与文件夹的基本操作,包括读取、写入、创建、删除和遍历等。通过示例代码展示了如何使用`os`和`io/ioutil`包进行文件操作,并强调了错误处理、权限控制和路径问题的重要性。适合初学者和有经验的开发者参考。
|
2月前
|
Java 大数据 Go
Go语言:高效并发的编程新星
【10月更文挑战第21】Go语言:高效并发的编程新星
53 7
|
2月前
|
Go 数据处理 调度
Go语言中的并发模型:解锁高效并行编程的秘诀
本文将探讨Go语言中独特的并发模型及其在现代软件开发中的应用。通过深入分析 Goroutines 和 Channels,我们将揭示这一模型如何简化并行编程,提升应用性能,并改变开发者处理并发任务的方式。不同于传统多线程编程,Go的并发方法以其简洁性和高效性脱颖而出,为开发者提供了一种全新的编程范式。
|
3月前
|
存储 缓存 Go
go语言编程系列(五)
go语言编程系列(五)
|
3月前
|
搜索推荐 Java 编译器
go语言编程系列(四)
go语言编程系列(四)
|
3月前
|
存储 JSON 安全
go语言编程系列(七)
go语言编程系列(七)