Skip to content

Instantly share code, notes, and snippets.

@isopov
Created January 29, 2025 13:03
Show Gist options
  • Save isopov/1091a375e32407626e1da1ccda461b70 to your computer and use it in GitHub Desktop.
Save isopov/1091a375e32407626e1da1ccda461b70 to your computer and use it in GitHub Desktop.
import (
"sync"
"testing"
"github.com/stretchr/testify/require"
)
var SliceBlackHole []int
func BenchmarkParallelNth(b *testing.B) {
for run := 0; run < b.N; run++ {
SliceBlackHole = runParallelNth()
}
}
func BenchmarkParallelBatches(b *testing.B) {
for run := 0; run < b.N; run++ {
SliceBlackHole = runParallelBatches()
}
}
func BenchmarkParallelToChannel(b *testing.B) {
for run := 0; run < b.N; run++ {
SliceBlackHole = runParallelToChannel()
}
}
func BenchmarkSimple(b *testing.B) {
for run := 0; run < b.N; run++ {
SliceBlackHole = runSimple()
}
}
const size = 1024
func runParallelNth() []int {
slice := make([]int, size)
threads := 8
wg := sync.WaitGroup{}
wg.Add(threads)
for i := 0; i < threads; i++ {
go func() {
for j := 0; j < size/threads; j++ {
sliceIndexAndVal := j*threads + i
slice[sliceIndexAndVal] = sliceIndexAndVal
}
wg.Done()
}()
}
wg.Wait()
return slice
}
func runParallelBatches() []int {
slice := make([]int, size)
threads := 8
wg := sync.WaitGroup{}
wg.Add(threads)
for i := 0; i < threads; i++ {
go func() {
for j := 0; j < size/threads; j++ {
sliceIndexAndVal := i*size/threads + j
slice[sliceIndexAndVal] = sliceIndexAndVal
}
wg.Done()
}()
}
wg.Wait()
return slice
}
func runParallelToChannel() []int {
results := make(chan int)
threads := 8
for i := 0; i < threads; i++ {
go func() {
for j := 0; j < size/threads; j++ {
sliceIndexAndVal := i*size/threads + j
results <- sliceIndexAndVal
}
}()
}
slice := make([]int, size)
for range size {
indexAndVal := <-results
slice[indexAndVal] = indexAndVal
}
return slice
}
func runSimple() []int {
slice := make([]int, size)
for i := range size {
slice[i] = i
}
return slice
}
func TestParallelNth(t *testing.T) {
result := runParallelNth()
require.Len(t, result, size)
for index, val := range result {
require.Equal(t, index, val)
}
}
func TestParallelBatches(t *testing.T) {
result := runParallelBatches()
require.Len(t, result, size)
for index, val := range result {
require.Equal(t, index, val)
}
}
func TestParallelToChannel(t *testing.T) {
result := runParallelToChannel()
require.Len(t, result, size)
for index, val := range result {
require.Equal(t, index, val)
}
}
func TestSimple(t *testing.T) {
result := runSimple()
require.Len(t, result, size)
for index, val := range result {
require.Equal(t, index, val)
}
}
@isopov
Copy link
Author

isopov commented Jan 29, 2025

goos: linux
goarch: amd64
cpu: Intel(R) Core(TM) i9-14900K
BenchmarkParallelNth
BenchmarkParallelNth-32          	  133501	     22480 ns/op
BenchmarkParallelBatches
BenchmarkParallelBatches-32      	   46422	     25960 ns/op
BenchmarkParallelToChannel
BenchmarkParallelToChannel-32    	    4028	    446858 ns/op
BenchmarkSimple
BenchmarkSimple-32               	  628676	      5208 ns/op
PASS

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