首页 后端开发 Golang 使用 Golang 进行基准测试

使用 Golang 进行基准测试

Sep 05, 2024 pm 09:31 PM

地鼠们你好?

在这篇博文中,我将向您展示如何使用 #golang 测试包中内置的出色工具。您将如何测试一段代码或函数的性能?使用基准测试。

我们走吧。

对于此测试,我将使用经典的斐波那契数列或斐波那契数列,它由以下因素确定:

if (x < 2) 
   F(0) = 1
   F(2) = 2
else 
   F(x) = F(x-1) + F(x-2)

In practice, the sequence is:
1, 1, 2, 3, 5, 8, 13, etc.
登录后复制

这个序列很重要,因为它也出现在数学和自然的多个部分中,如下所示:

Benchmark with Golang

有多种方法可以实现此代码,我将选择两种方法进行基准测试:计算它的递归方法和迭代方法。这些函数的主要目标是提供位置并返回该位置的斐波那契数。

递归法

// main.go

func fibRecursive(n int) int {
    if n <= 2 {
        return 1
    }
    return fibRecursive(n-1) + fibRecursive(n-2)
}
登录后复制

迭代法

// main.go

func fibIterative(position uint) uint {
    slc := make([]uint, position)
    slc[0] = 1
    slc[1] = 1

    if position <= 2 {
        return 1
    }

    var result, i uint
    for i = 2; i < position; i++ {
        result = slc[i-1] + slc[i-2]
        slc[i] = result
    }

    return result
}
登录后复制

这些方法并未经过优化,但即使对于少数情况,测试结果也有显着差异。您将在测试中看到这一点。要跟随代码进行操作,您可以点击此处。

现在,对于基准测试测试,让我们在 _main_test.go 文件中编写一些测试。使用 Golang 的 benchmark 文档,您可以创建要测试的函数,如下所示:

// main_test.go

// The key is to start every function you want to benchmark with the keyword Benchmark and use b *testing.B instead of t *testing.T as input 
func BenchmarkFibIterative(b *testing.B) {
    // Use this for-loop to ensure the code will behave correctly. 
    // Now, you can put the function or piece of code you want to test
    for i := 0; i < b.N; i++ { 
        fibIterative(uint(100))
    }
}

// Same as above
func BenchmarkFibRecursive(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fibRecursive(100)
    }
}
登录后复制

在继续之前问一个问题:哪个更快?

让我们对一个较小的数字 (10) 和一个稍大的数字 (80) 运行测试。要运行基准测试,您只需运行命令:

go test -bench=函数名称

如果您想了解更多有关此命令的信息,请查看此处。

第一次测试:position=10

//(fibIterative)
Results:
cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibIterative-8         24491042                42.50 ns/op
PASS
ok      playground      1.651s
登录后复制

让我们借助这张图来分析一下:

Benchmark with Golang

根据图像,我们有8个核心用于测试,没有时间限制(它将运行到完成)。花了1.651s完成任务。

==== Extra ====
We got 24,491,042 iterations (computations), and each iteration (op) took 42.50 ns.

Doing some math, we can calculate how much time one op took:

42.50 ns/op with 1 ns = 1/1,000,000,000 s
op ≈ 2.35270590588e-12 s
==== Extra ====
登录后复制

这是一个很好的结果。让我们检查一下位置 10 的递归函数:

// Results
BenchmarkFibRecursive-8          6035011               187.8 ns/op
PASS
ok      playground      1.882s
登录后复制

我们可以看到,完成任务花了1.882s

迭代函数以几十分之一的优势获胜。让我们再尝试一项测试:

位置 50

// Results for the Iterative Function

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibIterative-8         27896118                45.37 ns/op
PASS
ok      playground      2.876s

// Results for the Recursive Function

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibRecursive-8          6365198               186.3 ns/op
PASS
ok      playground      1.918s
登录后复制

哇!现在递归函数更快了?

让我们以稍微大一点的数字结束。

位置 80

// Results for the Iterative Function

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibIterative-8          5102344               229.5 ns/op
PASS
ok      playground      1.933s

// Results for the Recursive Function
// My poor PC couldn’t handle it, so I had to reduce the position to 50 just to get some results printed.

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibRecursive-8                1        44319299474 ns/op
PASS
ok      playground      44.951s
登录后复制

差异是巨大的。对于位置 80,迭代方法大约需要 2 秒。对于位置 50,递归函数花费了大约 45 秒。这证明了当您的 Golang 项目开始变慢时对代码进行基准测试的重要性。

结论

如果您的生产代码运行缓慢或不可预测地变慢,您可以使用此技术,结合 pprof 或内置测试包中的其他工具来识别和测试代码的执行位置不好以及如何优化它。

旁注:并非所有看起来漂亮的代码都具有更高的性能。

额外运动

你能找到更好的方法来改进递归函数吗? (提示:使用动态规划)。本文解释了为什么对于一些小数字,递归策略更好。

以上是使用 Golang 进行基准测试的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门文章

仓库:如何复兴队友
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
两个点博物馆:所有展览以及在哪里可以找到它们
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热门文章

仓库:如何复兴队友
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
两个点博物馆:所有展览以及在哪里可以找到它们
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热门文章标签

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Go语言包导入:带下划线和不带下划线的区别是什么? Go语言包导入:带下划线和不带下划线的区别是什么? Mar 03, 2025 pm 05:17 PM

Go语言包导入:带下划线和不带下划线的区别是什么?

如何编写模拟对象和存根以进行测试? 如何编写模拟对象和存根以进行测试? Mar 10, 2025 pm 05:38 PM

如何编写模拟对象和存根以进行测试?

Beego框架中NewFlash()函数如何实现页面间短暂信息传递? Beego框架中NewFlash()函数如何实现页面间短暂信息传递? Mar 03, 2025 pm 05:22 PM

Beego框架中NewFlash()函数如何实现页面间短暂信息传递?

如何定义GO中仿制药的自定义类型约束? 如何定义GO中仿制药的自定义类型约束? Mar 10, 2025 pm 03:20 PM

如何定义GO中仿制药的自定义类型约束?

如何使用跟踪工具了解GO应用程序的执行流? 如何使用跟踪工具了解GO应用程序的执行流? Mar 10, 2025 pm 05:36 PM

如何使用跟踪工具了解GO应用程序的执行流?

我如何使用衬里和静态分析工具来提高GO代码的质量和可维护性? 我如何使用衬里和静态分析工具来提高GO代码的质量和可维护性? Mar 10, 2025 pm 05:38 PM

我如何使用衬里和静态分析工具来提高GO代码的质量和可维护性?

Go语言如何便捷地写入文件? Go语言如何便捷地写入文件? Mar 03, 2025 pm 05:15 PM

Go语言如何便捷地写入文件?

Go语言中如何将MySQL查询结果List转换为自定义结构体切片? Go语言中如何将MySQL查询结果List转换为自定义结构体切片? Mar 03, 2025 pm 05:18 PM

Go语言中如何将MySQL查询结果List转换为自定义结构体切片?

See all articles