文章转载地址:https://www.flysnow.org/2017/05/21/go-in-action-go-benchmark-test.html

什么是基准测试?

     基准测试,是一种测试代码性能的方式,比如你有多种不同的方案,都可以解决问题,那么到底哪种方案性能

更好呢?这时候我们就可以使用基准测试

基准测试主要是通过测试 CPU 和 内存的效率,来评估被测试代码的性能,进而找到更好的解决方案

如何编写基准测试?

      基准测试代码的编写和单元测试非常相似,它也有一定的规则,看如下示例:

iota_test.go

package main_test

import (
"fmt"
"testing"
) func BenchmarkSprintf(b *testing.B) {
num := 10
b.ResetTimer()
for i := 0; i < b.N; i++{
fmt.Sprintf("%d",num)
}
} ----------------------------------------------- 输出结果: goos: windows
goarch: amd64
BenchmarkSprintf-8 20000000 93.0 ns/op
PASS
ok _/E_/GoProject/development/src 3.780s

  规则如下:

1.基准测试的代码文件必须以 _test.go 结尾

2.基准测试的函数必须以 Benchmark 开头,必须是可以导出的

3.基准测试的函数必须接受一个指向 Benchmark 类型的指针作为唯一参数

4.基准测试函数不能有返回值

5.b.ResetTimer 是重置计时器,这样可以避免 for 循环之前的初始化代码干扰

6.最后的 for 循环很重要,被测试的代码要放到 for 循环里

7. b.N 是基准测试框架提供的,表示循环的次数,因为需要反复调用测试的代码,才可以评估性能

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

基准测试的函数,. 表示运行所有基准测试

因为默认情况下,go test 会运行单元测试,为了防止单元测试的输出影响我们查看基准测的结果,我们可以

使用 -run 匹配一个从来没有的单元测试,过滤掉单元测试,我们这里使用 none,因为我们基本上不会创建这个名

字的单元测试方法

下面看一下输出结果的内容,我们可以看到在函数的后面有一个 -8 ,表示运行时对应的 GOMAXPROCS 的值。接着的

20000000 表示 for 循环的次数,也就是被测试代码调用的次数,最后的 93.0 ns/op 表示每次需要花费 93.0 纳秒

以上测试时间默认是 1s,也就是 1s 的时间被调用 20000000 次,每次花费 93.0 纳秒,如果想要测试运行的时间加长,

可以使用 -benchtime 指定,比如 3s,输出结果如下:

goos: windows
goarch: amd64
BenchmarkSprintf-8 50000000 97.5 ns/op
PASS
ok _/E_/GoProject/development/src 6.575s

  可以看到,加长了测试运行时间,测试被调用的次数变大了,但是每次调用花费的时间变化不大,一般来说测试运行的时间

不要超过 3s 意义不大

性能对比

        我们知道 Go 中将一个 int 类型转换成 string 类型常用的有三种方式,上面的基准测试是其中的一种,现在我们通过基准测试

来比较一下哪一种性能更高,如下示例:

package main_test

import (
"fmt"
"strconv"
"testing"
) // Sprintf 方式将 int 类型转换成 string 类型
func BenchmarkSprintf(b *testing.B) {
num := 10
b.ResetTimer() for i := 0; i < b.N; i++ {
fmt.Sprintf("%d",num)
}
} // Itoa 方式将 int 类型转换成 string类型
func BenchmarkItoa(b *testing.B) {
num := 10
b.ResetTimer() for i := 0; i < b.N; i++ {
strconv.Itoa(num)
}
} // 通过 FormatInt 方式将 int 类型转换成 string 类型
func BenchmarkFormatInt(b *testing.B) {
num := 10
b.ResetTimer() for i := 0; i < b.N; i++ {
strconv.FormatInt(int64(num),num)
}
} -------------------------------------------------------- 输出结果: goos: windows
goarch: amd64
BenchmarkSprintf-8 20000000 96.3 ns/op
BenchmarkItoa-8 300000000 4.13 ns/op
BenchmarkFormatInt-8 1000000000 2.94 ns/op
PASS
ok _/E_/GoProject/development/src 7.487s

  从运行结果上可以看到,strconv.FormatInt 函数最快,其次是 strconv.Itoa ,然后是 fmt.Sprintf 最慢,那么为什么

fmt.Sprintf 这么慢,现在我们通过 -benchmem 找一下具体原因,运行如下命令:

go test -bench=. -benchmem -run=none

----------------------------------------------

输出结果:

goos: windows
goarch: amd64
BenchmarkSprintf-8 20000000 95.4 ns/op 16 B/op 2 allocs/op
BenchmarkItoa-8 300000000 4.17 ns/op 0 B/op 0 allocs/op
BenchmarkFormatInt-8 1000000000 2.93 ns/op 0 B/op 0 allocs/op
PASS
ok _/E_/GoProject/development/src 7.396s

  -benchmem 可以提供每次操作分配内存的次数,以及每次操作分配的字节数,我们可以看到性能比较高的两个函数,

每次操作分配内存的次数都是 0,而最慢的那个每次操作分配内存的次数是 2;性能高的两个函数每次操作分配 0 字节内存,

最慢的那个每次操作分配 16 字节内存,从这个数据我们可以看出之所以慢的原因是内存分配占用太高

Go 基准测试的更多相关文章

  1. 一篇文章看懂TPCx-BB(大数据基准测试工具)源码

    TPCx-BB是大数据基准测试工具,它通过模拟零售商的30个应用场景,执行30个查询来衡量基于Hadoop的大数据系统的包括硬件和软件的性能.其中一些场景还用到了机器学习算法(聚类.线性回归等).为了 ...

  2. JavaScript的基准测试-不服跑个分?

    原文:Bulletproof JavaScript benchmarks 做JavaScript的基准测试并没有想的那么简单.即使不考虑浏览器差异所带来的影响,也有很多难点-或者说陷阱需要面对. 这是 ...

  3. mysql benchmark基准测试

    git项目地址: https://github.com/akopytov/sysbench 利用sysbench很容易对mysql做性能基准测试(当然这个工具很强大,除了测试主流数据库性能,还能测试其 ...

  4. 掌握 Linux PC 性能之基准测试

    导读 基准测试是一项测试或一系列测试,用来确定某个计算机硬件运行起来的状况有多好:在许多情况下,“基准测试”实际上等同于“压力测试”,通过测试硬件的极限,然后可以将测得的结果与其他硬件测得的结果作一番 ...

  5. mysql基准测试

    1. 及注册时有两种主要的策略:①正对整个系统的整体测试(集成式full-stack) ②单独测试mysql(但组件式基准测试single-component) 2.获取系统性能和状态(需要记录的数据 ...

  6. [译]使用JMH进行微基准测试:不要猜,要测试!

    英文原文:Micro Benchmarking with JMH: Measure, don't guess!翻译地址:使用JMH进行微基准测试:不要猜,要测试!原文作者:Antonio翻译作者:Ho ...

  7. Java监控工具介绍,VisualVm ,JProfiler,Perfino,Yourkit,Perf4J,JProbe,Java微基准测试

    本文是本人前一段时间做一个简单Java监控工具调研总结,主要包括VisualVm ,JProfiler,Perfino,Yourkit,Perf4J,JProbe,以及对Java微基准测试的简单介绍, ...

  8. Hadoop 基准测试与example

    #pi值示例 hadoop jar /app/cdh23502/share/hadoop/mapreduce2/hadoop-mapreduce-examples--cdh5. #生成数据 第一个参数 ...

  9. js 性能基准测试工具-告别可能、也许、大概这样更快更省

    平时写js经常遇到这样做是不是更快点?但又没有具体简单可测试的工具,最近也倒序看博客园司徒正美 js分类下的文章 [ps:去年灵光一闪,发现看博客园排名前100的博客.按照文章分类倒序看是学习最快的方 ...

  10. hadoop2.2基准测试

    <hadoop the definitive way>(third version)中的Benchmarking a Hadoop Cluster Test Cases的class在新的版 ...

随机推荐

  1. 在linux系统中出现u盘问题 的相关解决方法

    1.显示unknown filesystem type .exfat 可以通过该方法解决: 安装exfat-fuse: 在终端中以管理员身份运行 sudo apt-get install exfat- ...

  2. webpack4.27.1中遇到的错误

    1:ERROR in Entry module not found: Error: Can't resolve './src' 我在使用webpack命令时报错,这时因为我的配置文件有问题webpac ...

  3. Django系统

    #Django系统 -环境 - python3.6 - django1.8 -参考资料 - [django中文教程](http://python.usyiyi.cn) - django架站的16堂课 ...

  4. ArcGIS为面要素生成邻接矩阵

    1. 分析工具——>空间关联 使用注意,直接用FID似乎不可行,我是自己重新建了一个"String"字段,值用字段计算器从FID获取过来.之后按照上面的步骤才成功. 实现主要 ...

  5. mysql表类型导致的 setRollbackOnly() 事务不回滚

    在SpringBoot 中,使用事务非常简单,只需在方法上面加入 @Transactional  注解就可以实现.也可加在类上,此时则类中所有方法都支持事务. 而当我使用下面代码时,发现事务却没有回滚 ...

  6. Response内置对象

    request内置对象:主要用来处理用户的请求 response内置对象:处理对用户的响应(在调用service方法时容器会传递过来) response重要方法: public void addCoo ...

  7. Vue2leaflet 替换国内地图api,带{z}/{x}/{y}形式的

    参考:https://www.cnblogs.com/gispathfinder/p/9535685.html Vue2leaflet安装后,默认自带的地图URL如下 url:'http://{s}. ...

  8. git备注

    下拉仓库 git clone ""建立本地分支 git checkout -b "分支名字" 修改代码以后切换到主分支 git checkout master更 ...

  9. JavaScript实现循环链表

    单链表地址:点我 一.循环链表 节点的next指向下一个节点,节点的prev指向上一个节点 function loopList() { let length = 0, head = null, tai ...

  10. Django中怎么做图片上传--图片展示

    1.首先是html页面的form表单的三大属性,action是提交到哪,method是提交方式,enctype只要有图片上传就要加这个属性 Django框架自带csrf_token ,所以需要在前端页 ...