本文将主要做如下几方面的测试:
1,构造一个[100]struct的数组,然后来测试它的json编码后的字符串 或者([]byte),首先关心它的功能是否正常;
2,在很早之前,我们在使用golang版本的json编解码时,发现:同PHP的json编解码相比,golang的效率似乎要低,而且要低不少;
3,基于2的背景,我们希望测试新的golang版本中json编码方面是否有所提升,比较的版本是:Go1.3.3,Go1.9;
4,我们可以用程序的一次性执行来测试它的功能,但是如果多次测试,我们需要构造一个多次测试的环境;
关于3,我们需要做点功课,在同一台机器上部署两个版本的go:https://blog.csdn.net/min2015/article/details/77913910,这个博客或许能有所帮助。
另附:go的各个版本下载地址:https://golang.org/dl/
关于4,我们也需要做点功课,如何能用go test工具来辅助我们处理。这篇文章或许能帮助到我们:http://www.flysnow.org/2017/05/21/go-in-action-go-benchmark-test.html
实验环境准备:
1,创建一个目录,随便一个目录就行,比如我们叫json:mkdir json;
2,构造两个go文件:json.go, json_test.go
json.go代码如下:
json_test.go代码如下:
测试1:直接用go benchmark 来测试BenchmarkJson方法。
测试2:使用go benchmark的mem监控工具来测试BenchmarkJson方法。
可以看到带有-benchmem的选项时,在benchmark测试时能够知道内存分配的次数和内存大小。
测试3:作为和测试2的对比组,用go1.3.3来做测试。
测试对比结果如下:
测试2(Go1.9) | 测试3(Go1.3.3) | |
内存分配次数 | 59147 | 44184 |
内存分配大小(B) | 4957588 | 5078644 |
每次操作耗时 | 4.4ms | 8.99ms |
测试结果对比情况说明:go1.9的内存分配次数更多,但是每次操作耗时更短,依赖于go的版本升级(猜测:对json处理的优化,split hot stack的问题,由分配栈做link改为连续的内存)
而且这个对比结果还说明了,我们的程序有优化空间,100次的struct构建,却要花费44万次内存分配我们觉得有点扯。
基于这个有点扯的直觉,我们对程序进行了优化。
优化的重点放在了,GetText函数。
优化后的代码:
优化后的测试结果。
测试4:go1.9对优化再次benchmark。
测试5:go1.3.3.对优化再次benchmark
测试5,测试4,和之前的测试3,测试2,对比,每个op耗时更短,从测试2的4.4ms,降低到测试4的1.8ms。这个优化带来的效果是显著的,甚至比版本的升级带来的速度提升更明显。
测试2(Go1.9) | 测试3(Go1.3.3) | 测试4-优化(Go1.9) | 测试5-优化(Go1.3.3) | |
内存分配次数 | 59K | 44K | 314 | 268 |
内存分配大小 | 4.9MB | 5MB | 171KB | 171KB |
每次操作耗时 | 4.4ms | 8.99ms | 1.8ms | 2.2ms |
从程序的维度来看,这次优化带来的提升是显著的,在动态内存分配上[]byte要优于string的附加;
从Go版本的维度来看,Go1.9比Go1.3.3对json的编码速度而言,更有优势;
从工具的维度来看,go test更偏向于对功能的测试,go test benchmark更偏向于对程序的性能测试,而且benchmark是个很好的工具,它能够胜任较简单的模块测试,帮助我们发现模块中的性能问题。
如果对整个project做性能测试,pprof工具要更好,如果怀疑某个模块有问题,再在这个模块上使用benchmark来精准定位,是个合理的性能瓶颈定位方法。
附录: