Skip to content

Latest commit

 

History

History
103 lines (74 loc) · 2.16 KB

File metadata and controls

103 lines (74 loc) · 2.16 KB

概述

缓冲通道还是无缓冲通道,在高性能场景下,如何选择?

无缓冲通道测试代码

实现功能如下: 初始化一个 无缓冲通道,启动 N 个 goroutine 向通道写入数据,然后在 主 goroutine 读取通道数据,数据全部读取完成后关闭通道。

package performance

import (
	"sync"
	"testing"
)

func Benchmark_Compare(b *testing.B) {
	var wg sync.WaitGroup
	ch := make(chan struct{})

	for i := 0; i < b.N; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			<-ch
		}()
	}

	for i := 0; i < b.N; i++ {
		ch <- struct{}{}
	}

	wg.Wait()
	close(ch)
}

运行测试,并将基准测试结果写入文件:

$ go test -run='^$' -bench=. -count=1 -benchmem > nobuffer.txt 

缓冲通道测试代码

实现功能如下: 初始化一个 缓冲通道 (容量为 1024),启动 N 个 goroutine 向通道写入数据,然后在 主 goroutine 读取通道数据,数据全部读取完成后关闭通道。

package performance

import (
	"sync"
	"testing"
)

func Benchmark_Compare(b *testing.B) {
	var wg sync.WaitGroup
	ch := make(chan struct{}, 1024)

	for i := 0; i < b.N; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			<-ch
		}()
	}
    
	for i := 0; i < b.N; i++ {
		ch <- struct{}{}
	}

	wg.Wait()
	close(ch)
}

运行测试,并将基准测试结果写入文件:

$ go test -run='^$' -bench=. -count=1 -benchmem > buffer.txt

使用 benchstat 比较差异

$ benchstat -alpha=100 nobuffer.txt buffer.txt

# 输出如下
name        old time/op    new time/op    delta
_Compare-8    2.29µs ± 0%    1.94µs ± 0%  -15.14%  (p=1.000 n=1+1)

name        old alloc/op   new alloc/op   delta
_Compare-8      573B ± 0%      577B ± 0%   +0.70%  (p=1.000 n=1+1)

name        old allocs/op  new allocs/op  delta
_Compare-8      2.00 ± 0%      2.00 ± 0%     ~     (all equal)

从输出的结果中可以看到,通过 给通道设置缓冲容量, 性能可以优化 15% 左右。

小结

使用通道时,除了考虑 性能 因素外,还需要考虑场景语义,一个适用于大部分场景的万金油规则是: 设置通道缓冲容量为 1