diff --git a/fn/slice_test.go b/fn/slice_test.go index 7269f801e..7070431fc 100644 --- a/fn/slice_test.go +++ b/fn/slice_test.go @@ -676,3 +676,53 @@ func TestPropCollectOptionsNoNoneUnwrap(t *testing.T) { require.NoError(t, quick.Check(f, nil)) } + +// BenchmarkMapVsForEachConc benchmarks the performance of Map and ForEachConc +// for different workloads and slice sizes. It is used to show that ForEachConc +// is faster than Map when the workload is expensive. +func BenchmarkMapVsForEachConc(b *testing.B) { + // Test different workload types. + workloads := map[string]func(int) int{ + "Light": func(i int) int { + return i + 1 + }, + "Expensive": func(i int) int { + time.Sleep(time.Millisecond) + return i + 1 + }, + } + + // Test different slice sizes. + for _, size := range []int{10, 100, 1000} { + s := make([]int, size) + for i := range s { + s[i] = i + } + + for workload, inc := range workloads { + // Benchmark Map. + mapConf := fmt.Sprintf("Map-%s-Size-%d", workload, size) + b.Run(mapConf, func(b *testing.B) { + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + Map(s, inc) + } + }) + + // Benchmark ForEachConc. + concConf := fmt.Sprintf( + "ForEachConc-%s-Size-%d", workload, size, + ) + b.Run(concConf, func(b *testing.B) { + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + ForEachConc(s, inc) + } + }) + } + } +}