返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

9.2.3 性能

发布于 2024-10-12 19:15:49 字数 1301 浏览 0 评论 0 收藏 0

将发往通道的数据打包,减少传输次数,可有效提升性能。

通道内部实现有锁和数据复制操作,单次发送更多数据(批处理),可改善性能。

const (
	MAX    = 50000000 // 数据统计上限。
	BLOCK  = 500      // 数据块大小。
	CAP    = 100      // 缓冲区大小。
)

//go:noinline
func normal() {
	done := make(chan struct{})
	c := make(chan int, CAP)

	go func() {
		defer close(done)

		count := 0
		for x := range c {
			count += x
		}
	}()

	for i := 0; i < MAX; i++ {
		c <- i
	}

	close(c)
	<-done
}

//go:noinline
func block() {
	done := make(chan struct{})
	c := make(chan [BLOCK]int, CAP)

	go func() {
		defer close(done)

		count := 0
		for a := range c {
			for _, x := range a {
				count += x
			}
		}
	}()

	for i := 0; i < MAX; i += BLOCK {
        
		// 使用数组对数据打包。
		var b [BLOCK]int
		for n := 0; n < BLOCK; n++ {
			b[n] = i + n
			if i + n == MAX - 1 {
				break
			}
		}
        
		c <- b
	}

	close(c)
	<-done
}
func BenchmarkNormal(b *testing.B) {
	for i := 0; i < b.N; i++ {
		normal()
	}
}

func BenchmarkBlock(b *testing.B) {
	for i := 0; i < b.N; i++ {
		block()
	}
}
$ go test -bench . -benchmem

BenchmarkNormal-2   1   6573974400 ns/op     1848 B/op    8 allocs/op
BenchmarkBlock-2    8    138711262 ns/op   401528 B/op    3 allocs/op

测试并不严谨,有诸多干扰因素,结果也与数据量有关。仅供参考!

有关通道内部实现,可参考《源码剖析》。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文