Skip to content

Instantly share code, notes, and snippets.

@Jxck
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jxck/9184764 to your computer and use it in GitHub Desktop.
Save Jxck/9184764 to your computer and use it in GitHub Desktop.
benchmark of Generator in Go using Channel & Closure

on Mac Book Air (OSX 10.7.5) 1.6 GHz Intel Core i5 Memory 4GB

$ go test -bench .
PASS
BenchmarkClosure        100000000    11.5 ns/op
BenchmarkMutexClosure   50000000     35.3 ns/op
BenchmarkAtomicClosure  100000000    17.8 ns/op
BenchmarkChannel        5000000      251 ns/op
ok  /path/to/bench  6.747s
package generator
import (
"sync"
"sync/atomic"
)
func Closure() func() int {
i := 0
return func() int {
i = i + 1
return i
}
}
func MutexClosure() func() int {
var mutex = new(sync.Mutex)
i := 0
return func() int {
mutex.Lock()
defer mutex.Unlock()
i = i + 1
return i
}
}
func AtomicClosure() func() int32 {
var n int32 = 0
var i int32 = 1
return func() int32 {
// not goroutine safe
return atomic.AddInt32(&n, i)
}
}
func Channel() <-chan int {
ch := make(chan int)
go func() {
i := 1
for {
ch <- i
i = i + 1
}
}()
return ch
}
package generator
import (
"testing"
)
const TestCount = 1000000
func TestClosure(t *testing.T) {
cl := Closure()
for i := 1; i < TestCount; i++ {
actual := cl()
expected := i
if actual != expected {
t.Errorf("\ngot %v\nwant %v", actual, expected)
}
}
}
func TestMutexClosure(t *testing.T) {
cl := MutexClosure()
for i := 1; i < TestCount; i++ {
actual := cl()
expected := i
if actual != expected {
t.Errorf("\ngot %v\nwant %v", actual, expected)
}
}
}
func TestAtomicClosure(t *testing.T) {
cl := AtomicClosure()
var i int32
for i = 1; i < TestCount; i++ {
actual := cl()
expected := i
if actual != expected {
t.Errorf("\ngot %v\nwant %v", actual, expected)
}
}
}
func TestChannel(t *testing.T) {
ch := Channel()
for i := 1; i < TestCount; i++ {
actual := <-ch
expected := i
if actual != expected {
t.Errorf("\ngot %v\nwant %v", actual, expected)
}
}
}
func BenchmarkClosure(b *testing.B) {
cl := Closure()
b.ResetTimer()
for i := 0; i < b.N; i++ {
cl()
}
}
func BenchmarkMutexClosure(b *testing.B) {
cl := MutexClosure()
b.ResetTimer()
for i := 0; i < b.N; i++ {
cl()
}
}
func BenchmarkAtomicClosure(b *testing.B) {
cl := AtomicClosure()
b.ResetTimer()
for i := 0; i < b.N; i++ {
cl()
}
}
func BenchmarkChannel(b *testing.B) {
ch := Channel()
b.ResetTimer()
for i := 0; i < b.N; i++ {
<-ch
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment