From 25fe06d08ef91f82cd929e226362e91363ed4ad5 Mon Sep 17 00:00:00 2001 From: francisco souza <108725+fsouza@users.noreply.github.com> Date: Sat, 5 Mar 2022 17:44:59 -0500 Subject: [PATCH 1/2] parallel: remove mutex from Map and Times The slice is pre-allocated, a mutex is not needed. --- parallel/slice.go | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/parallel/slice.go b/parallel/slice.go index 34e17794..d531ae43 100644 --- a/parallel/slice.go +++ b/parallel/slice.go @@ -7,17 +7,14 @@ import "sync" func Map[T any, R any](collection []T, iteratee func(T, int) R) []R { result := make([]R, len(collection)) - var mu sync.Mutex var wg sync.WaitGroup wg.Add(len(collection)) for i, item := range collection { - go func (_item T, _i int) { + go func(_item T, _i int) { res := iteratee(_item, _i) - mu.Lock() result[_i] = res - mu.Unlock() wg.Done() }(item, i) @@ -35,7 +32,7 @@ func ForEach[T any](collection []T, iteratee func(T, int)) { wg.Add(len(collection)) for i, item := range collection { - go func (_item T, _i int) { + go func(_item T, _i int) { iteratee(_item, _i) wg.Done() }(item, i) @@ -50,7 +47,6 @@ func ForEach[T any](collection []T, iteratee func(T, int)) { func Times[T any](count int, iteratee func(int) T) []T { result := make([]T, count) - var mu sync.Mutex var wg sync.WaitGroup wg.Add(count) @@ -58,9 +54,7 @@ func Times[T any](count int, iteratee func(int) T) []T { go func(_i int) { item := iteratee(_i) - mu.Lock() result[_i] = item - mu.Unlock() wg.Done() }(i) @@ -81,7 +75,7 @@ func GroupBy[T any, U comparable](collection []T, iteratee func(T) U) map[U][]T wg.Add(len(collection)) for _, item := range collection { - go func (_item T) { + go func(_item T) { key := iteratee(_item) mu.Lock() @@ -91,7 +85,7 @@ func GroupBy[T any, U comparable](collection []T, iteratee func(T) U) map[U][]T } result[key] = append(result[key], _item) - + mu.Unlock() wg.Done() }(item) @@ -106,7 +100,7 @@ func GroupBy[T any, U comparable](collection []T, iteratee func(T) U) map[U][]T // determined by the order they occur in collection. The grouping is generated from the results // of running each element of collection through iteratee. // `iteratee` is call in parallel. -func PartitionBy[T any, K comparable](collection []T, iteratee func (x T) K) [][]T { +func PartitionBy[T any, K comparable](collection []T, iteratee func(x T) K) [][]T { result := [][]T{} seen := map[K]int{} From 770dff269b9c080e3dff8510a538cca500dce195 Mon Sep 17 00:00:00 2001 From: francisco souza <108725+fsouza@users.noreply.github.com> Date: Sat, 5 Mar 2022 18:26:37 -0500 Subject: [PATCH 2/2] Fix flaky test --- map_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/map_test.go b/map_test.go index 610d7305..79719918 100644 --- a/map_test.go +++ b/map_test.go @@ -30,6 +30,9 @@ func TestEntries(t *testing.T) { r1 := Entries[string, int](map[string]int{"foo": 1, "bar": 2}) + sort.Slice(r1, func(i, j int) bool { + return r1[i].Value < r1[j].Value + }) is.EqualValues(r1, []Entry[string, int]{ { Key: "foo",