Skip to content

Instantly share code, notes, and snippets.

@atotto
Created March 4, 2014 09:13
Show Gist options
  • Save atotto/9342938 to your computer and use it in GitHub Desktop.
Save atotto/9342938 to your computer and use it in GitHub Desktop.
golang channel benchmark
package chan_test
import (
"testing"
)
func BenchmarkStructChan(b *testing.B) {
ch := make(chan struct{})
go func() {
for {
<-ch
}
}()
for i := 0; i < b.N; i++ {
ch <- struct{}{}
}
}
func BenchmarkBoolChan(b *testing.B) {
ch := make(chan bool)
go func() {
for {
<-ch
}
}()
for i := 0; i < b.N; i++ {
ch <- true
}
}
func BenchmarkIntChan(b *testing.B) {
ch := make(chan int)
go func() {
for {
<-ch
}
}()
for i := 0; i < b.N; i++ {
ch <- 1
}
}
@rautelap
Copy link

rautelap commented Aug 31, 2017

To unsuspecting visitors to this page. Few things.

  1. This not how you should use channels, do not pass tiny amount of work over channels, pass around a chunk of work and work in batches. You will see almost horizontal scaling of the program using this simple technique.

  2. Results of the exact same bench on my 3.5GHz dual core Virtualbox VM

BenchmarkStructChan-2           10000000               172 ns/op               0 B/op          0 allocs/op
BenchmarkBoolChan-2             10000000               175 ns/op               0 B/op          0 allocs/op
BenchmarkIntChan-2              10000000               175 ns/op               0 B/op          0 allocs/op
PASS
ok      benchmarks/ifac2        5.800s

go version go1.8.3 linux/amd64

So, fret not. Go is fine, it requires a little bit of introspection. It ain't gonna do all the work for you on its own.
  1. With buffered channels
go test -bench=. -benchmem -benchtime=1s 


BenchmarkStructChan-2           20000000                59.0 ns/op             0 B/op          0 allocs/op
BenchmarkBoolChan-2             30000000                55.9 ns/op             0 B/op          0 allocs/op
BenchmarkIntChan-2              30000000                60.0 ns/op             0 B/op          0 allocs/op
PASS
ok      benchmarks/ifac2        4.991s

@sameer
Copy link

sameer commented Nov 23, 2017

To add onto that, if you were really trying to send one item at a time, you should be using a mutex from sync.

Here's what I got on a 2 vCPU (Haswell 3GHz) VPS with 1.6.2 and 1.9.2.

$ go version
go version go1.6.2 linux/amd64
$ go test -test.bench Bench
testing: warning: no tests to run
PASS
BenchmarkStructChan-2	 5000000	       260 ns/op
BenchmarkBoolChan-2  	 5000000	       283 ns/op
BenchmarkIntChan-2   	 5000000	       264 ns/op
ok  	_/root/test	4.948s

$ go version
go version go1.9.2 linux/amd64
$ go test -test.bench Bench
goos: linux
goarch: amd64
BenchmarkStructChan-2   	10000000	       258 ns/op
BenchmarkBoolChan-2     	 5000000	       243 ns/op
BenchmarkIntChan-2      	10000000	       234 ns/op
PASS
ok  	_/root/test	5.650s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment