学习
实践
活动
工具
TVP
写文章

Go语言字符串高效拼接(三)

在上一篇关于字符串拼接的文章Go语言字符串高效拼接(二)中,我们终于为拼接正名了,果真不负众望,尤其是拼接的字符串越来越多时,其性能的优越性更加明显。

在上一篇的结尾中,我留下悬念说其实还有优化的空间,这就是今天这篇文章,字符串拼接系列的第三篇,也是字符串拼接的最后一篇产生的原因,今天我们就看下如何再提升的性能。关于第一篇字符串高效拼接的文章可点击Go语言字符串高效拼接(一)查看。

Builder 慢在哪

既然要优化拼接,那么我们起码知道他慢在哪,我们继续使用我们上篇文章的测试用例,运行看下性能。

针对既然要优化拼接,采取了10、100、1000、10000四种不同数量的字符串进行拼接测试。我们发现每次操作都有不同次数的内存分配,内存分配越多,越慢,如果引起GC,就更慢了,首先我们先优化这个,减少内存分配的次数。

内存分配优化

通过cpuprofile,查看生成的火焰图可以得知,函数会被频繁的调用,并且时间占比也比较长。我们查看的源代码:

可以肯定是方法触发了,因为的容量不足,所以需要调用扩充的容量,然后才可以追加新的元素。扩容容量自然会涉及到内存的分配,而且追加的内容越多,内容分配的次数越多,这和我们上面性能测试的数据是一样的。

既然问题的原因找到了,那么我们就可以优化了,核心手段就是减少调用,甚至不调用。照着这个思路的话,我们就要提前为分配好容量。幸好为我们提供了扩充容量的方法,我们在进行之前,先通过方法,扩充好容量即可。

现在开始改造我们的函数。

增加一个参数,让使用者告诉我们需要的容量大小。方法的实现非常简单,就是一个通过函数,扩充大小,然后再拷贝的过程。

那么现在我们的性能测试用例变成如下:

为了说明情况和简短代码,这里只有10和1000个元素的用例,其他类似。为了把性能优化到极致,我一次性把需要的容量分配足够。现在我们再运行性能(Benchmark)测试代码。

性能足足翻了1倍多,只有1次内存分配,每次操作占用的内存也减少了一半多,降低了GC。

小结

这次优化,到了这里,算是结束了,写出来后,大家也会觉得不难,其背后的原理也非常情况,就是预先分配内存,减少过程中的内存重新分配和数据拷贝,这样我们就可以提升很多的性能。所以对于可以预见的长度的切,都可以提前申请申请好内存。

字符串拼接的系列,到这里结束了,一共三个系列,希望对大家所有帮助。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181112B0B69200?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券