Go 性能优化技巧 6/10

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 实现并发安全的计数器,或序号生成器。 架构

性能测试结果代表,差别远比想的要大得多。单就此例而言,还能够用原子操做(atomic)进一步优化。 并发

若是说 channel 适用于结构层面解耦,那么 mutex 则适合保护语句级别的数据安全。至于 atomic,虽然也可实现 lock-free 结构,但处理起来要复杂得多(好比 ABA 等问题),也未必就比 mutex 快不少。还有,sync.Mutex 本就没有使用内核实现,而是像 Futex 那样,直接在用户空间以 atomic 操做完成,由于 runtime 没有任何理由将剩余 CPU 时间片还给内核。 性能

从没一种技术或技巧适用于全部场合。不管是表达,或者选型,都不该该脱离实际场景(上下文)。另外,就本系列的优化技巧而言,除非真有必要,不然大可没必要理会这些 “奇技淫巧”。至于担忧可否适应将来变化,我以为多余。由于不管是架构、算法,亦或者是这些技巧,你本就应该有相应的机制确保在 “变化” 发生时第一时间获知。再者说,技巧并不是照抄,无非多种思路而已。知其形,明其意,方为正理。 学习



最新动态,请扫码关注 测试

相关文章
相关标签/搜索