有缓冲vs无缓冲channel

默认情况下,通道是无缓冲的。
发送数据的协程和接收数据的协程都会在通道上阻塞,除非发送方已经发送了数据而且已经被接收方接收。
坚持让每次发送/接收操作都同步,会造成不必要的性能减速。
想象一个场景,一个协程生产数据,另外的协程消费数据。
假设发送一次和接收一次数据都各耗时1秒,则需要耗费2*N秒来生产和消费所有数据。
如果生产者可以将多个值放入通道,生产者也不必等待消费者拿走每个数据。
这就是有缓冲channel的工作。
通过允许生产者独立于消费者继续向下执行,我们可以为某些场景加速。
package main
import (
"fmt"
"time"
)
func producer(ch chan int) {
for i := 0; i < 5; i++ {
if i%2 == 0 {
time.Sleep(10 * time.Millisecond)
} else {
time.Sleep(1 * time.Millisecond)
}
ch <- i
}
}
func consumer(ch chan int) {
total := 0
for i := 0; i < 5; i++ {
if i%2 == 1 {
time.Sleep(10 * time.Millisecond)
} else {
time.Sleep(1 * time.Millisecond)
}
total += <-ch
}
}
func unbuffered() {
timeStart := time.Now()
ch := make(chan int)
go producer(ch)
consumer(ch)
fmt.Printf("Unbuffered version took %s\n", time.Since(timeStart))
}
func buffered() {
timeStart := time.Now()
ch := make(chan int, 5)
go producer(ch)
consumer(ch)
fmt.Printf("Buffered version took %s\n", time.Since(timeStart))
}
func main() {
unbuffered()
buffered()
}
-------------Output----------------
Unbuffered version took 54.8527ms
Buffered version took 36.9019ms