Go 性能优化技巧 6/10

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

Go 使用 channel 实现 CSP 模型。处理双方仅关注通道和数据本身,无需理会对方身份和数量,以此实现结构性解耦。在各文宣中都有 “Don't communicate by sharing memory, share memory by communicating.” 这类说法。但这并非鼓励我们不分场合,教条地使用 channel。 在我看来,channel 多数时候适用于结构层面,而非单个区域的数据处理。原话中 “communicate” 本就表明一种 “message-passing”,而非 “lock-free”。所以,它并非用来取代 mutex,各自有不同的使用场景。 有关 channel 实现方式,可参考《Go 学习笔记》第五版,下卷《源码剖析》。 从实现角度看,channel 算是一种很 “重” 的实现。在小粒度层面,其性能真算不得好。我们可用一个常见示例测试一下:用 channel 实现并发安全的计数器,或序号生成器。 ![channel1](http://studygolang.qiniudn.com/160603/965399121b7701a70de79a69b0ffec74.jpg) ![channel2](http://studygolang.qiniudn.com/160603/91dc328f40594c49020e39c69f4205e8.jpg) ![channel3](http://studygolang.qiniudn.com/160603/470305fcadfef8b92f2bb5d98c9c5d36.jpg) 性能测试结果表明,差异远比想的要大得多。单就此例而言,还可以用原子操作(atomic)进一步优化。 ![atomic1](http://studygolang.qiniudn.com/160603/bdf6374f8ff1a7f2c0848599d40a35b3.jpg) ![atomic2](http://studygolang.qiniudn.com/160603/663daf55ae53c939bf5ed0652d3a2f1c.jpg) ![atomic3](http://studygolang.qiniudn.com/160603/95c9abdc25c45a94718a984516be7e7a.jpg) 如果说 channel 适用于结构层面解耦,那么 mutex 则适合保护语句级别的数据安全。至于 atomic,虽然也可实现 lock-free 结构,但处理起来要复杂得多(比如 ABA 等问题),也未必就比 mutex 快很多。还有,sync.Mutex 本就没有使用内核实现,而是像 Futex 那样,直接在用户空间以 atomic 操作完成,因为 runtime 没有任何理由将剩余 CPU 时间片还给内核。 从没一种技术或技巧适用于所有场合。无论是表达,或者选型,都不应该脱离实际场景(上下文)。另外,就本系列的优化技巧而言,除非真有必要,否则大可不必理会这些 “奇技淫巧”。至于担心能否适应未来变化,我觉得多余。因为无论是架构、算法,亦或者是这些技巧,你本就应该有相应的机制确保在 “变化” 发生时第一时间获知。再者说,技巧并非照抄,无非多种思路而已。知其形,明其意,方为正理。

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

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

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