Skip to content

Instantly share code, notes, and snippets.

@hnakamur
Last active July 11, 2017 01:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hnakamur/a61b781c2db27868fe6ed0c26ecc5a23 to your computer and use it in GitHub Desktop.
Save hnakamur/a61b781c2db27868fe6ed0c26ecc5a23 to your computer and use it in GitHub Desktop.
package main_test
import (
"crypto/rand"
"runtime"
"testing"
)
func BenchmarkBaseline(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
var b [16]byte
for pb.Next() {
rand.Read(b[:])
runtime.Gosched()
}
})
}
var c chan [16]byte
func init() {
c = make(chan [16]byte, 1000)
go func(c chan [16]byte) {
for {
var b [16]byte
rand.Read(b[:])
c <- b
}
}(c)
}
func BenchmarkChannel(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
<-c
runtime.Gosched()
}
})
}
func BenchmarkAmortized(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
var b [256]byte
var count int64
for pb.Next() {
cur := count & 0xF
count++
if cur == 0 {
rand.Read(b[:])
}
start, end := cur*16, (cur+1)*16
_ = b[start:end]
runtime.Gosched()
}
})
}
var ac chan [16]byte
func init() {
ac = make(chan [16]byte, 1000)
var b [256]byte
var count int64
go func(ac chan [16]byte) {
for {
cur := count & 0xF
count++
if cur == 0 {
rand.Read(b[:])
}
start, end := cur*16, (cur+1)*16
var out [16]byte
copy(out[:], b[start:end])
ac <- out
}
}(ac)
}
func BenchmarkChannelAmortized(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
<-ac
runtime.Gosched()
}
})
}
var crr []chan [16]byte
func init() {
crr = make([]chan [16]byte, 32)
for i := range crr {
c = make(chan [16]byte, 1000)
go func(c chan [16]byte) {
for {
var b [16]byte
rand.Read(b[:])
c <- b
}
}(c)
crr[i] = c
}
}
func BenchmarkChannelRoundRobin(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
var count int
for pb.Next() {
count++
cur := count % len(crr)
<-crr[cur]
runtime.Gosched()
}
})
}
var cmw chan [16]byte
func init() {
cmw = make(chan [16]byte, 1000)
for i := 0; i < 32; i++ {
go func(cmw chan [16]byte) {
for {
var b [16]byte
rand.Read(b[:])
cmw <- b
}
}(cmw)
}
}
func BenchmarkChannelManyWriters(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
<-cmw
runtime.Gosched()
}
})
}
var acmw chan [16]byte
func init() {
acmw = make(chan [16]byte, 1000)
for i := 0; i < 32; i++ {
go func(acmw chan [16]byte) {
var b [256]byte
var count int64
for {
cur := count & 0xF
count++
if cur == 0 {
rand.Read(b[:])
}
start, end := cur*16, (cur+1)*16
var out [16]byte
copy(out[:], b[start:end])
acmw <- out
}
}(acmw)
}
}
func BenchmarkChannelAmortizedManyWriters(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
<-acmw
runtime.Gosched()
}
})
}
@hnakamur
Copy link
Author

$ time go test -bench . -count 1000 -timeout 24h -benchmem 2>&1 | tee -a results
testing: warning: no tests to run
PASS
BenchmarkBaseline-2                      1000000              1303 ns/op               0 B/op          0 allocs/op
BenchmarkBaseline-2                      1000000              1314 ns/op               0 B/op          0 allocs/op
...(snip)...
ok      blog.sgmansfield.com    8797.114s

real    146m37.826s
user    61m51.600s
sys     188m1.404s


$ awk '{print $1, $2, $3, $4}' results > results.op
$ benchstat results.op
name                           time/op
Baseline-2                     1.32µs ± 1%
Channel-2                      1.49µs ± 1%
Amortized-2                    1.05µs ± 6%
ChannelAmortized-2             1.03µs ± 1%
ChannelRoundRobin-2            1.30µs ± 0%
ChannelManyWriters-2           1.28µs ± 1%
ChannelAmortizedManyWriters-2  1.19µs ± 1%

$ go version
go version go1.6.2 linux/amd64

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