如何在Golang中测试for循环与递归两种算法的运行速度和内存占用
Go语言测试函数运行速度与内存占用的方案
方案1:使用官方标准库testing的基准测试(最推荐,结果最准确)
Go原生自带基准测试工具,不需要引入第三方依赖,能直接输出准确的耗时、内存分配数据:
- 首先去掉两个函数里的
fmt.Println代码,IO操作的耗时远高于循环、递归本身的逻辑开销,会严重干扰测试结果。修改后函数如下:
func forLoop(a int) { for i := a; i >= 0; i-- { // 移除打印逻辑避免影响测试结果 } } func recursive(a int) int { if a <= 0 { return 0 } return recursive(a - 1) }
- 同级目录下新建基准测试文件,命名为
xxx_test.go,比如algorithm_test.go,写入以下测试代码:
package 你的代码包名 import "testing" // 测试for循环版本 func BenchmarkForLoop(b *testing.B) { // 重置计时器,排除初始化逻辑的耗时影响 b.ResetTimer() for i := 0; i < b.N; i++ { // 把参数换成你要测试的入参,比如100 forLoop(100) } } // 测试递归版本 func BenchmarkRecursive(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { recursive(100) } }
- 终端执行测试命令:
go test -bench=. -benchmem - 输出结果说明:
- 第一列是测试函数名
- 第二列是运行的总次数,工具会自动调整次数保证结果可信度
- 第三列
ns/op是单次运行的平均耗时(单位纳秒) - 第四列
B/op是单次运行分配的内存字节数 - 第五列
allocs/op是单次运行的内存分配次数
方案2:手动单次测试(适合快速验证)
如果不想写基准测试文件,也可以用标准库的time包计时,runtime包读取内存占用,缺点是误差相对更大,只适合做大致对比:
package main import ( "fmt" "runtime" "time" ) // 这里放你修改后的forLoop、recursive函数,移除打印逻辑 func main() { a := 100 // 测试for循环 start := time.Now() var m1 runtime.MemStats runtime.ReadMemStats(&m1) beforeAlloc := m1.TotalAlloc forLoop(a) var m2 runtime.MemStats runtime.ReadMemStats(&m2) afterAlloc := m2.TotalAlloc cost := time.Since(start) fmt.Printf("for循环耗时:%v,内存分配:%d字节\n", cost, afterAlloc - beforeAlloc) // 测试递归 start = time.Now() runtime.ReadMemStats(&m1) beforeAlloc = m1.TotalAlloc recursive(a) runtime.ReadMemStats(&m2) afterAlloc = m2.TotalAlloc cost = time.Since(start) fmt.Printf("递归耗时:%v,内存分配:%d字节\n", cost, afterAlloc - beforeAlloc) }
注意事项
- 递归版本如果入参
a的数值过大会触发栈溢出,Go的栈大小有限,递归深度太高会直接崩溃 - 一定要去掉测试逻辑里的IO操作,否则打印的耗时会占99%以上,完全测不准函数本身的性能
内容的提问来源于stack exchange,提问作者Hamka Satria
相关产品推荐
相关产品推荐

