本文介绍golang 如何做基准性能测试。

编写完代码除了跑必要的单元测试外,还需要考虑代码跑起来的性能如何。性能的衡量其实就是程序运行时候进程的内存分配,CPU消耗情况。

golang 语言在提供了功能测试的基础上,提供了丰富的性能测试功能。

SHOW CODE

首先,从一个例子来讲起。 随便写一个简单的快速排序,然后和系统自带的排序做一个性能比较。

如下为简版快排的代码:

package benchmark

import "sort"

func QSort(data []int) {
myqsort(data, 0, len(data)-1)
} func myqsort(data []int, s, e int) {
if s >= e {
return
} t := data[s]
i, j := s, e for i < j {
for ; i < j && data[j] >= t; j-- { }
for ; i < j && data[i] < t; i++ { }
if i < j { break } data[i], data[j] = data[j], data[i]
i++
j--
} data[i] = t
myqsort(data, s, i-1)
myqsort(data, i+1, e)
}

然后编写一个测试的test。

package benchmark

import "testing"
import "math/rand"
import "time"
import "sort" var ints []int // 长度为 1w 的数据使用系统自带排序
func BenchmarkSort10k(t *testing.B) {
slice := ints[0:10000]
t.ResetTimer() // 只考虑下面代码的运行事件,所以重置计时器
for i := 0; i < t.N; i++ {
sort.Ints(slice)
}
} // 长度为 100 的数据使用系统自带排序
func BenchmarkSort100(t *testing.B) {
slice := ints[0:100]
t.ResetTimer()
for i := 0; i < t.N; i++ {
sort.Ints(slice)
}
} // 长度为 1w 的数据使用上述代码排序
func BenchmarkQsort10k(t *testing.B) {
slice := ints[0:10000]
t.ResetTimer()
for i := 0; i < t.N; i++ {
QSort(slice)
}
} // 长度为 100 的数据使用上述代码排序
func BenchmarkQsort100(t *testing.B) {
slice := ints[0:100]
t.ResetTimer()
for i := 0; i < t.N; i++ {
QSort(slice)
}
} // 数据初始化,为了保证每次数据都是一致的。
func TestMain(m *testing.M) {
rand.Seed(time.Now().Unix())
ints = make([]int, 10000) for i := 0; i < 10000; i++ {
ints[i] = rand.Int()
} m.Run()
}

运行命令 :

# go test -cover -count 3  -benchmem  -bench=.

运行结果如下图:

基准测试,默认将每个方法执行1s中,然后展示执行的次数,每一次执行的耗时, 上述还展示了内存每次分配的大小,以及每次benchmark分配的次数。上述的命令行指定了运行次数为3次,显示代码覆盖率和内存分配情况。

从基准测试的结果可以分析出:对于1w数据量的排序,自带的排序比我的排序算法要快20倍左右;100数据量的排序,手撸的排序略胜一筹。

从内存分析来讲,系统自带的会使用4B的数据,而我的算法无内存分配。

INTRODUCE BENCHMARK

引入golang 提供的 testing 包,写需要的基准测试的方法(方法名必须以Benchmark开头, 参数必须为 *testing.B)。

若需要做一些数据初始化的工作,可以如上写一个TestMain 方法,将数据初始化的工作在这里完成。

除了这些,可以看*testing.B, *testing.M 的相关方法即可。

最后,只要运行官方提供的 go test -bench=. 命令,即可开始跑基准测试。 当然,还有其他选项可以满足我们多样的需求。

例如:

  • -cpu 1,2,4 指定运行的cpu 格式
  • -count n 指定运行的次数
  • -benchtime 每一条测试执行的时间 (默认是1s)
  • -bench 指定执行bench的方法, . 是全部
  • -benchmem 显示内存分配情况

其他参数可以通过 go help testflag 查看

WHY SO SLOW

  1. 我这里选取的是第一个数作为中位数,数据越大越可能出现倾斜,排序慢的概率也大。
  2. 正常的排序包中,都会在对小于等于12 个数的数组做排序时使用希尔排序,速度也有很大提升。

除了简单的做性能测试外,golang 还自带了性能分析的工具,我们可以快速找出代码中的内存分配、cpu消耗的核心区,帮助我们解决服务的性能问题。下篇文章将做详细了解。

golang 性能测试 (1)的更多相关文章

  1. golang 性能测试pprof

    golang 性能测试包是位于 net/http 包下的 pprof,其相关介绍可以参看具体的 官方文档 有关 golang 性能测试使用特别简单,在 main 包中的引包位置直接引入: import ...

  2. Golang 性能测试 (3) 跟踪刨析 golang trace

    简介 对于绝大部分服务,跟踪刨析是用不到的.但是如果遇到了下面问题,可以不妨一试: 怀疑哪个协程慢了 系统调用有问题 协程调度问题 (chan 交互.互斥锁.信号量等) 怀疑是 gc (Garbage ...

  3. Golang 语言的单元测试和性能测试(也叫 压力测试)

    Golang单元测试对文件名和方法名,参数都有很严格的要求. 例如: 1.文件名必须以xx_test.go命名 2.方法必须是Test[^a-z]开头(T必须大写),func TestXxx (t * ...

  4. golang bufio、ioutil读文件的速度比较(性能测试)和影响因素分析

    前言 golang读取文件的方式主要有4种: 使用File自带的Read方法 使用bufio库的Read方法 使用io/ioutil库的ReadAll() 使用io/ioutil库的ReadFile( ...

  5. 基本http服务性能测试(Python vs Golang)

    最近学习Golang,总想体验下并发到底有多叼,必我大 python强势多少. 学习了官方教程的http 服务,用性能测试工具wrk测试了下,发现结果很令人惊讶- wrk可以参考我的博客,有基本用法说 ...

  6. Golang RPC 性能测试

    Golang RPC 性能测试 | KDF5000 http://kdf5000.com/2017/03/28/Golang-RPC-性能测试/

  7. golang 单元测试&&性能测试

    一:单元测试 1.为什么要做单元测试和性能测试 减少bug 快速定位bug 减少调试时间 提高代码质量 2.golang的单元测试 单元测试代码的go文件必须以_test.go结尾 单元测试的函数名必 ...

  8. LevelDB性能测试|Golang调用LevelDB

    LevelDB性能测试|Golang调用LevelDB 不同方式使用压力测试 用ssdb,TCP连接方式调用,底层存储levelDB 直接调用Cgo的levelDB (必须保证串行) 直接调用Gola ...

  9. 【GoLang】GoLang 单元测试、性能测试使用方法

    单元测试代码: ackage test import ( // "fmt" "testing" ) func Test_FlowControl(t *testi ...

随机推荐

  1. Redis07——Redis到底能用在什么地方(下)

    在前一篇文章中,我们已经介绍过Redis的一些实际应用.如KV缓存.分布式锁.消息队列,由于篇幅原因,并未介绍完全.接下来将继续为各位带来Redis的更多应用. bitmat(位图) 实现 位图的基本 ...

  2. [android]R.class里有ID,onCreate方法里调用findViewById返回空

    在做android练习,一个新手错误,记录一下: 在练习android权威编程指南时,第5章 第二个Activity部分练习,出现标题问题,代码还原如下: protected void onCreat ...

  3. 03、MySql的数据类型

    MySQL中定义数据字段的类型对你数据库的优化是非常重要的. MySQL支持多种类型,大致可以分为三类:数值.日期/时间和字符串(字符)类型. 1.数字类型 类型 大小 范围(有符号) 范围(无符号) ...

  4. centos7安装部署opentsdb2.4.0

    写在前面 安装HBase 在HBase中创建表结构 安装配置并启动opentsdb 写在前面 最近因为项目需要在读opentsdb的一部分源码,后面会做个小结分享出来.本人是不大喜欢写这种安装部署的文 ...

  5. debug.js在手机上打印调试信息

    在做移动端开发的时候大家应该都遇到过这么一个问题:如何在手机上打印调试信息? 在pc端我们通常会用console.log 或者 alert,但大家知道console.log在手机上是看不到打印信息的: ...

  6. 分布式——吞吐量巨强、Hbase的承载者 LSMT

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是分布式系统的第九篇文章. 今天给大家分享的内容是LSM树,它的英文是Log-structed Merge-tree.看着有些发怵,但其 ...

  7. Kubernetes中Pod健康检查

    目录 1.何为健康检查 2.探针分类 2.1.LivenessProbe探针(存活性探测) 2.2.ReadinessProbe探针(就绪型探测) 3.探针实现方法 3.1.Container Exe ...

  8. 手写简单IOC

    ReflectUtils.java (反射工具类) package top.icss.ioc; import java.io.File; import java.io.FileFilter; impo ...

  9. GPP(Group Policy Preference)组策略偏好漏洞利用

    总结与反思: GPP中管理员给域成员添加的账号信息存在xml,可以直接破解拿到账号密码. Windows Sever 2008 的组策略选项(GPP)是一个新引入的插件,方便管理员管理的同时也引入了安 ...

  10. 采用C++实现哈夫曼树的创建并输出哈夫曼编码

    一.这篇随笔来自一道信息论的作业题,因为手动编码过于复杂,所以想到了编程解决,原题目如下图所示: 二.源代码如下: #include <iostream> #include <str ...