Go性能优化技巧1/10

qyuhen · · 3949 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

字符串(string)作为一种不可变类型,在与字节数组(slice, [ ]byte)转换时需付出 “沉重” 代价,根本原因是对底层字节数组的复制。这种代价会在以万为单位的高并发压力下迅速放大,所以对它的优化常变成 “必须” 行为。 首先,须了解 string 和 [ ]byte 数据结构,并确认默认方式的复制行为。 ![source](http://studygolang.qiniudn.com/160428/a01e98e972abb87f20d0dc9edaa1fd17.jpg) ![gdb](http://studygolang.qiniudn.com/160428/4069f099cbb9753061fb4acf82227a46.jpg) 动态演示: [https://asciinema.org/a/6up6gvgqo0v9zkjpusvyucg8g](https://asciinema.org/a/6up6gvgqo0v9zkjpusvyucg8g) 从 GDB 输出结果可看出,转换后 [ ]byte 底层数组与原 string 内部指针并不相同,以此可确定数据被复制。那么,如不修改数据,仅转换类型,是否可避开复制,从而提升性能? 从 ptype 输出的结构来看,string 可看做 [2]uintptr,而 [ ]byte 则是 [3]uintptr,这便于我们编写代码,无需额外定义结构类型。如此,str2bytes 只需构建 [3]uintptr{ptr, len, len},而 bytes2str 更简单,直接转换指针类型,忽略掉 cap 即可。 ![source](http://studygolang.qiniudn.com/160428/5059ac3e11afabfc205e6dc070356415.jpg) 用 unsafe 完成指针类型转换,所以得自行为底层数组生命周期做出保证。好在这两个函数都很简单,编译器会完成内联处理,并未发生逃逸行为。 ![source](http://studygolang.qiniudn.com/160428/6ff6d23c6624779284adc53ed3dc0da2.jpg) 对比一下优化前后的性能差异。 ![source](http://studygolang.qiniudn.com/160428/6bd0e436431193f049ef2fc3e49edb22.jpg) ![gdb](http://studygolang.qiniudn.com/160428/ebea36433a7311fdaabb915d486a5a37.jpg) 性能提升明显,最关键的是 zero-garbage。 **提示:仅在必要的时候做此优化!**

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:1006366459

3949 次点击  ∙  6 赞  
加入收藏 微博
2 回复  |  直到 2016-06-01 08:20:28
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传