在编写代码时常使用且常忽视的性能问题进行总结。这篇文章将持续更新…
string 和 []byte 相互转换
无论是从哪种类型转换到另一种都需要对其中的内容进行拷贝,string 和 []byte 相互转换 也不例外,内存拷贝的性能损耗会随着字符串数组和字节长度的增长而增长,所以在做这种类型转换时一定要注意性能上的问题。
接下来我们可以使用一些方法来避免这种大批量的拷贝工作,这个方法就是可以绕过类型检查的 unsafe.Pointer
1 | func str2bytes(s string) []byte { |
字符串连接
字符串连接有很多方法:
- 直接通过运算符
+
- fmt.Sprintf()
- bytes.Buffer{}
1 | func Buffer(str ...string) string { |
- strings.Builder{}
1 | func Builder(str ...string) string { |
- copy方法
1 | func Copy(str ...string) string { |
既然方法有这么多种,性能问题就会有差异,通过benchmark测试查看一下:
可以看出copy和strings.Builder性能上是最好的,fmt.Sprintf是最差的,为什么呢?要知道golang 里面的字符串都是不可变的,每次运算都会产生一个新的字符串,所以会产生很多临时的无用的字符串,不仅没有用,还会给 gc 带来额外的负担,所以性能变差。而copy和strings.Builder根据长度预先分配内存,没有产生很多临时的无用的字符串。本质上就是以空间换时间。
json序列化
json系列我们最常用的就是标准库里的encoding/json,但为提高性能可以使用一些第三方库替换。如json-iterator、easyjson等。
性能提升多少呢?我们通过banchmark测试看一下:
可以看到json-iterator和easyjson相比easyjson提升整整一倍。但第三方库有一定的维护成本,但数据量大的时候,使用第三方库也是值得的。