Skip to content

Commit

Permalink
🕜 perf: Optimize zarray.Map
Browse files Browse the repository at this point in the history
  • Loading branch information
sohaha committed Jul 4, 2024
1 parent aaa914e commit 8d0970f
Showing 1 changed file with 23 additions and 27 deletions.
50 changes: 23 additions & 27 deletions zarray/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ package zarray

import (
"math/rand"
"sync/atomic"

"github.com/sohaha/zlsgo/zstring"
"github.com/sohaha/zlsgo/zsync"
"github.com/sohaha/zlsgo/zutil"
)

// CopySlice copy a slice.
Expand All @@ -31,49 +31,45 @@ func Rand[T any](collection []T) T {
}

// Map manipulates a slice and transforms it to a slice of another type.
func Map[T any, R any](collection []T, iteratee func(int, T) R) []R {
res := make([]R, len(collection))
func Map[T any, R any](collection []T, iteratee func(int, T) R, parallel ...uint) []R {
colLen := len(collection)
res := make([]R, colLen)

for i, item := range collection {
res[i] = iteratee(i, item)
}

return res
}

// ParallelMap Parallel manipulates a slice and transforms it to a slice of another type.
// If the calculation does not involve time-consuming operations, we recommend using a Map.
func ParallelMap[T any, R any](collection []T, iteratee func(int, T) R, workers uint) []R {
inLen, workTotal := len(collection), int(workers)

res := make([]R, inLen)
if inLen == 0 {
if len(parallel) == 0 {
for i := range collection {
res[i] = iteratee(i, collection[i])
}
return res
}

if inLen < workTotal {
workTotal = inLen
} else if workTotal == 0 {
workTotal = 1
}
var (
idx atomic.Int64

Check failure on line 46 in zarray/slice.go

View workflow job for this annotation

GitHub Actions / build (1.18, SQLite3)

undefined: atomic.Int64
wg zsync.WaitGroup
)

idx := zutil.NewInt64(0)
task := func() {
i := int(idx.Add(1) - 1)
for ; i < inLen; i = int(idx.Add(1) - 1) {
for ; i < colLen; i = int(idx.Add(1) - 1) {
res[i] = iteratee(i, collection[i])
}
}

var wg zsync.WaitGroup
for i := 0; i < workTotal; i++ {
for i := 0; i < int(parallel[0]); i++ {
wg.Go(task)
}
_ = wg.Wait()

wg.Wait()

return res
}

// ParallelMap Parallel manipulates a slice and transforms it to a slice of another type.
// If the calculation does not involve time-consuming operations, we recommend using a Map.
// Deprecated: please use Map
func ParallelMap[T any, R any](collection []T, iteratee func(int, T) R, workers uint) []R {
return Map(collection, iteratee, workers)
}

// Shuffle creates a slice of shuffled values.
func Shuffle[T any](collection []T) []T {
n := CopySlice(collection)
Expand Down

0 comments on commit 8d0970f

Please sign in to comment.