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

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


相关文章
|
人工智能 自然语言处理 安全
学不会编程也能写测试?AI让测试更平权
在传统的软件开发体系中,测试常被划分为“技术型测试”(如自动化、性能、安全)和“业务型测试”(如功能验证、用户体验)。前者掌握技术话语权,后者则更多依赖经验和流程规范。然而,随着大语言模型(LLM)等AI技术的迅猛发展,这一固有格局正被悄然打破:
533 10
|
测试技术 程序员 Go
Go语言测试简明指南:深度解读go test命令
总的来说,go test是 Go 语言中一个强而有力的工具,每个 Go 程序员都应该掌握并把它融入到日常的开发和调试过程中。就像是一个眼镜过滤出的太阳,让我们在宽阔的代码海洋中游泳,而不是淹没。用好它,让我们的代码更健壮,让我们的生产力更强效。
857 23
|
设计模式 缓存 算法
Go如何进行高质量编程与性能调优实践
本文介绍了Go语言高质量编程与性能调优的实践方法。高质量编程包括良好的编码习惯(如清晰注释、命名规范)、代码风格与设计(如MVC模式)、简洁明了的代码原则,以及单元测试与代码重构的重要性。性能调优方面,涵盖算法优化、数据结构选择、I/O优化、内存管理、并行与并发处理优化及代码层面的改进。通过这些方法,可有效提升代码质量和系统性能。
277 13
|
分布式计算 Go C++
初探Go语言RPC编程手法
总的来说,Go语言的RPC编程是一种强大的工具,让分布式计算变得简单如同本地计算。如果你还没有试过,不妨挑战一下这个新的编程领域,你可能会发现新的世界。
332 10
|
机器学习/深度学习 设计模式 测试技术
Python 高级编程与实战:构建自动化测试框架
本文深入探讨了Python中的自动化测试框架,包括unittest、pytest和nose2,并通过实战项目帮助读者掌握这些技术。文中详细介绍了各框架的基本用法和示例代码,助力开发者快速验证代码正确性,减少手动测试工作量。学习资源推荐包括Python官方文档及Real Python等网站。
|
人工智能 自然语言处理 前端开发
CodeArena:在线 LLM 编程竞技场!用于测试不同开源 LLM 的编程能力,实时更新排行榜
CodeArena 是一个在线平台,用于测试和比较不同大型语言模型(LLM)的编程能力。通过实时显示多个 LLM 的代码生成过程和结果,帮助开发者选择适合的 LLM,并推动 LLM 技术的发展。
2881 7
CodeArena:在线 LLM 编程竞技场!用于测试不同开源 LLM 的编程能力,实时更新排行榜
|
数据采集 监控 Java
go语言编程学习
【11月更文挑战第3天】
385 7
|
数据库连接 Go 数据库
Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性
本文探讨了Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性;防御编程则强调在编码时考虑各种错误情况,确保程序健壮性。文章详细介绍了这两种技术在Go语言中的实现方法及其重要性,旨在提升软件质量和可靠性。
335 1
|
测试技术 Go
go语言中测试工具
【10月更文挑战第22天】
361 4
|
Java 大数据 Go
Go语言:高效并发的编程新星
【10月更文挑战第21】Go语言:高效并发的编程新星
566 7

热门文章

最新文章