什么是基准测试

基准测试,是一种测试代码性能的方法,比如你有多种不同的方案,都可以解决问题,那么到底是那种方案性能更好呢?这时候基准测试就派上用场了。

基准测试主要是通过测试CPU和内存的效率问题,来评估被测试代码的性能,进而找到更好的解决方案。比如链接池的数量不是越多越好,那么哪个值才是最优值呢,这就需要配合基准测试不断调优了。

如何编写基准测试

基准测试代码的编写和单元测试非常相似,它也有一定的规则,我们先看一个示例。

itoa_test.go

package gotest

import (
"fmt"
"testing"
) //itoa_test.go
func BenchmarkSprintf(b *testing.B) {
num := 10
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Sprintf("%d", num)
}
}

  

这是一个基准测试的例子,从中我们可以看出以下规则:

  • 基准测试的代码文件必须以_test.go结尾
  • 基准测试的函数必须以Benchmark开头,必须是可导出的
  • 基准测试函数必须接受一个指向Benchmark类型的指针作为唯一参数
  • 基准测试函数不能有返回值
    b.ResetTimer是重置计时器,这样可以避免for循环之前的初始化代码的干扰
    最后的for循环很重要,被测试的代码要放到循环里
    b.N是基准测试框架提供的,表示循环的次数,因为需要反复调用测试的代码,才可以评估性能
    下面我们运行下基准测试,看看效果。

运行基准测试也要使用go test命令,不过我们要加上-bench=标记,它接受一个表达式作为参数,匹配基准测试的函数,.表示运行所有基准测试。

因为默认情况下go test 会运行单元测试,为了防止单元测试的输出影响我们查看基准测试的结果,可以使用-run=匹配一个从来没有的单元测试方法,过滤掉单元测试的输出,我们这里使用none,因为我们基本上不会创建这个名字的单元测试方法。

下面着重解释下说出的结果,看到函数后面的-2了吗?这个表示运行时对应的GOMAXPROCS的值。接着的5000000表示运行for循环的次数,也就是调用被测试代码的次数,最后的290 ns/op表示每次需要话费290纳秒。

以上是测试时间默认是1秒,也就是1秒的时间,调用5000000次,每次调用花费290纳秒。如果想让测试运行的时间更长,可以通过-benchtime指定,比如3秒。

可以发现,我们加长了测试时间,测试的次数变多了,但是最终的性能结果:每次执行的时间,并没有太大变化。一般来说这个值最好不要超过3秒,意义不大。

性能对比

上面那个基准测试的例子,其实是一个int类型转为string类型的例子,标准库里还有几种方法,我们看下哪种性能更加。

package gotest

import (
"fmt"
"strconv"
"testing"
) func BenchmarkSprintf(b *testing.B) {
num := 10
b.ResetTimer()
for i := 0; i < b.N; i++ {
fmt.Sprintf("%d", num)
}
} func BenchmarkFormat(b *testing.B) {
num := int64(10)
b.ResetTimer()
for i := 0; i < b.N; i++ {
strconv.FormatInt(num, 10)
}
} func BenchmarkItoa(b *testing.B) {
num := 10
b.ResetTimer()
for i := 0; i < b.N; i++ {
strconv.Itoa(num)
}
}

  运行基准测试,看看结果

从结果上看strconv.FormatInt函数是最快的,其次是strconv.Itoa,然后是fmt.Sprintf最慢,前两个函数性能达到了最后一个的10倍多。那么最后一个为什么这么慢的,我们再通过-benchmem找到根本原因。

-benchmem可以提供每次操作分配内存的次数,以及每次操作分配的字节数。allocs/op 表示每次操作从堆上分配内存的次数。B/op 表示每次操作分配的字节数。
从结果我们可以看到,性能高的两个函数,每次操作都是进行0次内存分配,而最慢的那个要分配2次;性能高的每次操作分配8个字节内存,而慢的那个函数每次需要分配0字节的内存。从这个数据我们就知道它为什么这么慢了,内存分配都占用都太高。

在代码开发中,对于我们要求性能的地方,编写基准测试非常重要,这有助于我们开发出性能更好的代码。不过性能、可用性、复用性等也要有一个相对的取舍,不能为了追求性能而过度优化。

Golang ---基准测试的更多相关文章

  1. Golang 基准测试Benchmark

    基准测试 Go语言标准库内置的 testing 测试框架提供了基准测试(benchmark)的能力,实现了对某个特定目标场景的某项性能指标进行定量的和可对比的测试. 基本规则 基准测试的代码文件必须以 ...

  2. VS Code对Golang的基准测试研究

    初心 想要在VS Code比较方便的调试Go代码的性能,了解到基准测试对此很有帮助,但默认VS Code执行 Go 的基准测试默认的benchtime为1秒,但测试性能时需要设置为更多秒 办法 在VS ...

  3. 说说Golang的使用心得

    13年上半年接触了Golang,对Golang十分喜爱.现在是2015年,离春节还有几天,从开始学习到现在的一年半时间里,前前后后也用Golang写了些代码,其中包括业余时间的,也有产品项目中的.一直 ...

  4. 经济学人使用Golang构建微服务历程回顾

    关键点 经济学人内容分发系统需要更大的灵活性,将内容传递给日益多样化的数字渠道.为了实现这一灵活性目标并保持高水平的性能和可靠性,平台从一个单体结构过渡到微服务体系结构. 用Go编写的服务是新系统的一 ...

  5. golang学习资料[Basic]

    http://devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang/index.html 基础语法 <Go By Exa ...

  6. Go单元测试与基准测试

    Go单元测试 Go单元测试框架,遵循规则整理如下: 1.文件命名规则: 含有单元测试代码的go文件必须以_test.go结尾,Go语言测试工具只认符合这个规则的文件 单元测试文件名_test.go前面 ...

  7. golang 单元测试(一)

    单元测试函数类型 Test(功能测试) 函数规则: 函数名: TestXxxx , 以Test为前缀.Xxxx以大写字母开头 参数类型: *testing.T func TestXxxx(t *tes ...

  8. golang单元测试简述

      Golang中内置了对单元测试的支持,不需要像Java一样引入第三方Jar才能进行测试,下面将分别介绍Golang所支持的几种测试: 一.测试类型   Golang中单元测试有功能测试.基准测试. ...

  9. golang 性能测试 (1)

    本文介绍golang 如何做基准性能测试. 编写完代码除了跑必要的单元测试外,还需要考虑代码跑起来的性能如何.性能的衡量其实就是程序运行时候进程的内存分配,CPU消耗情况. golang 语言在提供了 ...

随机推荐

  1. vue----子组件引用vux popup mask遮罩在最上层解决办法 z-index问题

    在一个页面的子组件中引用vux的popup组件时,出现mask遮罩在最上层的问题,百度了一下发现有两种解决办法,现提供第三种. popup在子组件引用时,vux将vux-popup-mask默认添加到 ...

  2. 【Alpha】“北航社团帮”小程序v1.0测试报告

    目录 测试计划.过程和结果 后端单元测试 后端压力测试 测试结果 指标解释 前端测试 授权登录与权限检查 功能测试 兼容性测试 性能测试 回答课程组问题 测试中发现的bug 场景测试 测试矩阵 出口条 ...

  3. 【技术博客】Pytorch代码生成

    开发组在开发过程中,都不可避免地遇到了一些困难或问题,但都最终想出办法克服了.我们认为这样的经验是有必要记录下来的,因此就有了[技术博客]. Pytorch代码生成经验文档 关于模型代码的生成,主要思 ...

  4. 剑指offer:数据流中的中位数

    题目描述: 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我 ...

  5. 剑指offer:把数组排成最小的数

    题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路分析: ...

  6. 高通qxdm抓取sensor的log【学习笔记】

    高通qxdm抓取sensor的log 打开qxdm,打开设置界面,去掉其他无关的log,打开Log packets .Message packets的SNS的log 之后需要把端口打开,把端口打开之后 ...

  7. 微信小程序图片宽度100%,高度自适应

    实现图片自适应,按照一般情况只需设置: img { width: 100%; height: auto; } 但是微信小程序里是特例,需要image标签上设置属性mode=widthFix,就是hei ...

  8. 用PMML实现python机器学习模型的跨平台上线

    python信用评分卡(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_camp ...

  9. android ------ 高版本的 Tablayout 下划线宽度

    前面呢,有写过TabLayout的博客,最近开发用到了高本版遇到一些问题,来总结一下 Android--------TabLayout实现新闻客户端顶部导航栏 Android中Tablayout设置下 ...

  10. 【大数据】Spark On Yarn

    Spark在YARN中有yarn-cluster和yarn-client两种运行模式: I. Yarn client 在yarn-client模式下,Driver运行在Client上,通过Applic ...