惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
Engineering at Meta
Engineering at Meta
D
DataBreaches.Net
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog
Y
Y Combinator Blog
B
Blog RSS Feed
GbyAI
GbyAI
P
Proofpoint News Feed
aimingoo的专栏
aimingoo的专栏
MyScale Blog
MyScale Blog
D
Docker
阮一峰的网络日志
阮一峰的网络日志
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recorded Future
Recorded Future
美团技术团队
The Register - Security
The Register - Security
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
The Blog of Author Tim Ferriss
博客园 - 司徒正美
量子位
B
Blog
F
Fortinet All Blogs
Martin Fowler
Martin Fowler
博客园 - 【当耐特】
MongoDB | Blog
MongoDB | Blog
A
About on SuperTechFans
I
InfoQ
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
有赞技术团队
有赞技术团队
雷峰网
雷峰网
大猫的无限游戏
大猫的无限游戏
J
Java Code Geeks
L
LangChain Blog
Latest news
Latest news
S
SegmentFault 最新的问题
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Blog — PlanetScale
Blog — PlanetScale
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cisco Talos Blog
Cisco Talos Blog
F
Full Disclosure
C
Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
W
WeLiveSecurity
T
Tenable Blog
T
Tor Project blog

Razeen`s Blog

Let's Encrypt 推出 Gen Y 根证书架构:揭示 Web PKI 的五大未来趋势 通过 Wi-Fi 自动备份你的 iPhone 到 Nas 管理培训感悟:从技术视角看管理之路 UPS 一拖多:保护你的 NAS 和 Linux 服务器 从影音中心到 AI 助手:我的50款 Homelab 服务清单 从SSL证书有效期将缩短到47天聊开去 部署一个自己的 Running Page 谈谈特斯拉 Model Y 用车一年的感受和费用分析 弃用 Disqus 评论,使用自建 Waline 使用 Prometheus 和 Grafana 搭建你的证书监控面板 服务器迁移记:一次磁盘换板引发的Linux分区与挂载的学习 改善信息来源, 利用 RSS 高效获取资讯 (RSShub + Reeder5 + WeWe RSS) 多种 Docker 镜像拉取解决方案与实践 App分享 | AppCleaner - Mac上的卸载神器 Azure OpenAI API 申请和使用 如何开通 OneKey 虚拟信用卡,并充值消费 如何拥有一个可长期在国内使用的国外手机号码 分享开通 ChatGPT Plus 过程 如何开通 Depay 虚拟信用卡,并充值消费 如何开通欧易Web3钱包, 交易入账 如何5分钟内1块钱注册 ChatGPT 如何注册美区的 Apple ID (2023年/无需科学上网) NAS折腾记(11): NASTool3.0体验和降级 NAS折腾记(10): Docker版本的NASTool配置 NAS折腾记(9): NASTool与微信交互,微信发送消息远程下载电影【多图】 NAS折腾记(8):群晖安装 NASTool 实现影音半自动化【多图】 内网穿透(2):Tailscale 组网实现内网穿透,操作简单,无成本 内网穿透(1):总结了11中内网穿透的方式,总有一种适合你 NAS折腾记(7):从零开始设置(黑)群晖系统 NAS折腾记(6):黑群晖系统安装好后怎么洗白? NAS折腾记(5):群晖硬盘休眠设置与分析 NAS折腾记(4): 20分钟手把手带你完美安装 DS918+ 黑群晖7.1.1 NAS折腾记(3):NAS 装机 NAS折腾记(2):B360-ITX 双M.2 双2.5G网口 6 SATA主版 开箱 NAS折腾记(1):328元的4盘位Nas机箱开箱 Openwrt + Clash 全局科学上网 Newifi3 刷入 OpenWrt 固件 v21.02 利用 Markdown 画一些流程图、时序图、甘特图等 Homelab(8): 搭建自用 Gitlab 与 Docker 仓库 Nginx Tcp 转发保留客户端真实 IP (PROXY Protocol) Homelab (7):IPSec VPN(基于证书认证)客户端设置 Homelab (6): 基于自签发证书的 IPSec VPN 搭建 Homelab (5): DDNS 动态域名解析 Homelab (4): Linux 服务器基础环境准备 Homelab (3): 整体网络与基础硬件介绍 Go学习笔记(十)老项目迁移 go module 大型灾难记录 Github Actions 初体验之自动化部署 Hexo 博客 记一次 Nginx DNS 缓存导致转发问题 Homelab (2): 电信悦me网关修改桥接模式,路由器拨号 Homelab (1):5分钟上手黑群晖 NAS 终极 Bash 脚本指南 Typora 自动上传图片到七牛云 Ubuntu 20.04 LTS 有线网卡驱动安装 折腾 Ubuntu 20.04 LTS 开发环境 Go学习笔记(九) 计时器的生命周期[译] 利用 git hook 规范你的代码与 commit message 规范 git commit message 与自动化版本控制 超详细 vim 配置 (with MacVim) Golang 中的 RESTful API 最佳实践 折腾服务器(开篇) 我的第一台个人服务器 Newifi3 实现低成本家庭级科学上网 Go学习笔记(八) | 使用 os/exec 执行命令 如何用 Go 调用 Windows API Mac OS 自动根据 WI-FI 名字改变网络位置 关于 Docker 清理 MIME Types 速查表 Go学习笔记(七) | 理解OAuth 2.0并实现一个客户端 我又又又把博客迁移了 Go学习笔记(六) | 使用swaggo自动生成Restful API文档 Go学习笔记(五) | 使用代码片段(snippets)提高编码效率 书单 - 2018 IPFS 初体验,利用 IPFS 托管你的静态网站 记一次 PostgreSQL LIKE 索引优化,联合字段 LIKE 查询优化。 Disqus 添加有趣的 Reactions 的功能 TLS 1.3 详解 (RFC 8446解读) gRPC在Go中的使用(三)gRPC实现TLS加密通信与流模式 gRPC在Go中的使用(二)gRPC实现简单通讯 gRPC在Go中的使用(一)Protocol Buffers语法与相关使用 CentOS 安装 tshark 抓包工具 Go学习笔记(四) | win上使用VSCode搭建Go开发环境 日常 Postgres 数据库点滴记录 简单了解 PKCS 规范 美食篇 | DIY戚风蛋糕(烤箱做蛋糕) TLS1.3正式更新,为Nginx添加TLS1.3的支持 一次诡异的数据库删除 GitHub Pages自定义域名开启HTTPS 证书透明度是什么?它是怎么工作的? Go学习笔记(二) | 我对 recover 的一点误解 搭建证书透明度(certificate-transparency)日志服务之从入门到放弃 修复远程登陆 Centos 时,出现 UTF-8 Warning HTTPS篇之SSL握手过程详解 Go学习笔记(一) | postgres与golang点点滴滴 AWS 命令行界面(aws-cli)从安装到快速上手 数字证书分类及怎么区分各类数字证书 常用 linux 命令小结(一)文件目录操作 云服务器搭建 hexo 博客,git hooks自动更新 SSH 免密登陆, SSH Config 配置 Golang CGO Mac 交叉编译 Windows 使用 goose 让数据库迁移更加轻松 开始使用Ghost
Go学习笔记(三) | 怎么写Go基准测试(性能测试)
2018-04-25 · via Razeen`s Blog

或许你经常会思考这样的问题,我用不同的方法实现了同样的效果,哪个会更快?哪个内存消耗更小?这时候你一个简单的基准测试就能解决你的疑惑。

Go向来是以工具丰富而著称的,在学习Go的过程中,你会发现无论是写一个单元测试,还是做一些竞争检测都能很快的上手,而且用的很痛快。当然,接下来要说的基准测试也一样。

基准测试工具就在Go的测试包中,下面就用一个例子来介绍。

举个栗子

由于一些场景需要,我需要将[]byte输出16进制字符。

有时候我会这么写:

但有时候我会这么写:

但到底哪种写法更好呢?今天我就来比较一下。

直接写了个main.go

func EncodeA(b []byte) string {
	return fmt.Sprintf("%x", b)
}

func EncodeB(b []byte) string {
	return hex.EncodeToString(b)
}

再写个测试main_test.go

var buf = []byte("skdjadialsdgasadasdhsakdjsahlskdjagloqweiqwo")

func BenchmarkEncodeA(b *testing.B) {
	for i := 0; i < b.N; i++ {
		EncodeA(buf)
	}
}

func BenchmarkEncodeB(b *testing.B) {
	for i := 0; i < b.N; i++ {
		EncodeB(buf)
	}
}

就这么简单,我们的基本测试就写完了。从我的写法中你也许就知道:

  • 和单元测试一样,都写在_test.go文件中;
  • 需要以Benchmark为函数名开头;
  • 和单元测试类似,必须接受一个*testing.B参数;
  • 被测试代码放在一个循环中。

我们直接跑一下。当然我们也是用go test来执行测试,简单的测试只要带上-bench=.就可以了。

$ go test -bench=.
goos: darwin
goarch: amd64
pkg: github.com/razeencheng/demo-go/benchmark
BenchmarkEncodeA-8       5000000               265 ns/op
BenchmarkEncodeB-8      10000000               161 ns/op
PASS
ok      github.com/razeencheng/demo-go/benchmark        3.397s

前两行是平台信息,第三行包名。第四、五行就是测试的结果了。

  • BenchmarkEncodeA-8 ,BenchmarkEncodeB-8 基准测试函数名-GOMAXPROCS
  • 5000000,10000000 被测试的函数执行次数,也就是EncodeA()被执行了5000000次,EncodeB()被执行了10000000次,也就是b.N的值了。
  • 265 ns/op,161 ns/op表示每次调用被测试函数花费的时间。

从花费的时间上来看,我们知道EncodeB()要快一点。

更多

你以为就这么简单的结束了么?NONONO。

  • -bench 可接收一个有效的正则表达式来执行符合条件的测试函数。当你的函数很多时,可以用它来过滤.
$ go test -bench=BenchmarkEncodeA
goos: darwin
goarch: amd64
pkg: github.com/razeencheng/demo-go/benchmark
BenchmarkEncodeA-8       5000000               256 ns/op
PASS
ok      github.com/razeencheng/demo-go/benchmark        1.575s
  • -benchmem可以查看内存分配
$ go test -bench=. -benchmem
goos: darwin
goarch: amd64
pkg: github.com/razeencheng/demo-go/benchmark
BenchmarkEncodeA-8       5000000               261 ns/op             128 B/op          2 allocs/op
BenchmarkEncodeB-8      10000000               162 ns/op             192 B/op          2 allocs/op
PASS
ok      github.com/razeencheng/demo-go/benchmark        3.408s

其中B/op 表示每次执行会分配多少内存,allocs/op表示每次执行会发生多少次内存分配。

  • -benchtime指定每个测试执行的时间。默认1s,当你的函数比较耗时你可以设置更长一点。因为b.N是与这个时间有关的。

    当你的运行时间没达到-benchtime制定的时间前,b.N将以1,2,5,10,20,50…增加,然后重新运行测试代码。

    $ go test -bench=. -benchmem -benchtime=5s
    goos: darwin
    goarch: amd64
    pkg: github.com/razeencheng/demo-go/benchmark
    BenchmarkEncodeA-8      30000000               254 ns/op             128 B/op          2 allocs/op
    BenchmarkEncodeB-8      50000000               160 ns/op             192 B/op          2 allocs/op
    PASS
    ok      github.com/razeencheng/demo-go/benchmark        16.113s  
    
  • -count指定每个测试执行的次数。

$ go test -bench=. -benchmem -count=3
goos: darwin
goarch: amd64
pkg: github.com/razeencheng/demo-go/benchmark
BenchmarkEncodeA-8       5000000               256 ns/op             128 B/op          2 allocs/op
BenchmarkEncodeA-8       5000000               255 ns/op             128 B/op          2 allocs/op
BenchmarkEncodeA-8       5000000               253 ns/op             128 B/op          2 allocs/op
BenchmarkEncodeB-8      10000000               163 ns/op             192 B/op          2 allocs/op
BenchmarkEncodeB-8      10000000               160 ns/op             192 B/op          2 allocs/op
BenchmarkEncodeB-8      10000000               160 ns/op             192 B/op          2 allocs/op
PASS
ok      github.com/razeencheng/demo-go/benchmark        9.984s

我常用的也就这些了。

但对于testing.B来说,它拥有了testing.T的全部接口,所以Fail,Skip,Error这些都可以用,而且还增加了

  • SetBytes( i uint64) 统计内存消耗。
  • SetParallelism(p int) 制定并行数目。
  • StartTimer / StopTimer / ResertTimer 操作计时器。

你可以按需使用。

注意

b.N为一个自增字段,谨慎用它做函数参数。