Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: speed up loops by reducing allocations #475

Merged
merged 1 commit into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ func SliceToChannel[T any](bufferSize int, collection []T) <-chan T {
ch := make(chan T, bufferSize)

go func() {
for _, item := range collection {
ch <- item
for i := range collection {
ch <- collection[i]
}

close(ch)
Expand Down Expand Up @@ -265,13 +265,13 @@ func FanIn[T any](channelBufferCap int, upstreams ...<-chan T) <-chan T {

// Start an output goroutine for each input channel in upstreams.
wg.Add(len(upstreams))
for _, c := range upstreams {
go func(c <-chan T) {
for n := range c {
for i := range upstreams {
go func(index int) {
for n := range upstreams[index] {
out <- n
}
wg.Done()
}(c)
}(i)
}

// Start a goroutine to close out once all the output goroutines are done.
Expand Down
80 changes: 40 additions & 40 deletions find.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
// IndexOf returns the index at which the first occurrence of a value is found in an array or return -1
// if the value cannot be found.
func IndexOf[T comparable](collection []T, element T) int {
for i, item := range collection {
if item == element {
for i := range collection {
if collection[i] == element {
return i
}
}
Expand All @@ -38,9 +38,9 @@ func LastIndexOf[T comparable](collection []T, element T) int {

// Find search an element in a slice based on a predicate. It returns element and true if element was found.
func Find[T any](collection []T, predicate func(item T) bool) (T, bool) {
for _, item := range collection {
if predicate(item) {
return item, true
for i := range collection {
if predicate(collection[i]) {
return collection[i], true
}
}

Expand All @@ -51,9 +51,9 @@ func Find[T any](collection []T, predicate func(item T) bool) (T, bool) {
// FindIndexOf searches an element in a slice based on a predicate and returns the index and true.
// It returns -1 and false if the element is not found.
func FindIndexOf[T any](collection []T, predicate func(item T) bool) (T, int, bool) {
for i, item := range collection {
if predicate(item) {
return item, i, true
for i := range collection {
if predicate(collection[i]) {
return collection[i], i, true
}
}

Expand All @@ -78,9 +78,9 @@ func FindLastIndexOf[T any](collection []T, predicate func(item T) bool) (T, int

// FindOrElse search an element in a slice based on a predicate. It returns the element if found or a given fallback value otherwise.
func FindOrElse[T any](collection []T, fallback T, predicate func(item T) bool) T {
for _, item := range collection {
if predicate(item) {
return item
for i := range collection {
if predicate(collection[i]) {
return collection[i]
}
}

Expand All @@ -89,8 +89,8 @@ func FindOrElse[T any](collection []T, fallback T, predicate func(item T) bool)

// FindKey returns the key of the first value matching.
func FindKey[K comparable, V comparable](object map[K]V, value V) (K, bool) {
for k, v := range object {
if v == value {
for k := range object {
if object[k] == value {
return k, true
}
}
Expand All @@ -100,8 +100,8 @@ func FindKey[K comparable, V comparable](object map[K]V, value V) (K, bool) {

// FindKeyBy returns the key of the first element predicate returns truthy for.
func FindKeyBy[K comparable, V any](object map[K]V, predicate func(key K, value V) bool) (K, bool) {
for k, v := range object {
if predicate(k, v) {
for k := range object {
if predicate(k, object[k]) {
return k, true
}
}
Expand All @@ -114,20 +114,20 @@ func FindKeyBy[K comparable, V any](object map[K]V, predicate func(key K, value
func FindUniques[T comparable](collection []T) []T {
isDupl := make(map[T]bool, len(collection))

for _, item := range collection {
duplicated, ok := isDupl[item]
for i := range collection {
duplicated, ok := isDupl[collection[i]]
if !ok {
isDupl[item] = false
isDupl[collection[i]] = false
} else if !duplicated {
isDupl[item] = true
isDupl[collection[i]] = true
}
}

result := make([]T, 0, len(collection)-len(isDupl))

for _, item := range collection {
if duplicated := isDupl[item]; !duplicated {
result = append(result, item)
for i := range collection {
if duplicated := isDupl[collection[i]]; !duplicated {
result = append(result, collection[i])
}
}

Expand All @@ -140,8 +140,8 @@ func FindUniques[T comparable](collection []T) []T {
func FindUniquesBy[T any, U comparable](collection []T, iteratee func(item T) U) []T {
isDupl := make(map[U]bool, len(collection))

for _, item := range collection {
key := iteratee(item)
for i := range collection {
key := iteratee(collection[i])

duplicated, ok := isDupl[key]
if !ok {
Expand All @@ -153,11 +153,11 @@ func FindUniquesBy[T any, U comparable](collection []T, iteratee func(item T) U)

result := make([]T, 0, len(collection)-len(isDupl))

for _, item := range collection {
key := iteratee(item)
for i := range collection {
key := iteratee(collection[i])

if duplicated := isDupl[key]; !duplicated {
result = append(result, item)
result = append(result, collection[i])
}
}

Expand All @@ -169,21 +169,21 @@ func FindUniquesBy[T any, U comparable](collection []T, iteratee func(item T) U)
func FindDuplicates[T comparable](collection []T) []T {
isDupl := make(map[T]bool, len(collection))

for _, item := range collection {
duplicated, ok := isDupl[item]
for i := range collection {
duplicated, ok := isDupl[collection[i]]
if !ok {
isDupl[item] = false
isDupl[collection[i]] = false
} else if !duplicated {
isDupl[item] = true
isDupl[collection[i]] = true
}
}

result := make([]T, 0, len(collection)-len(isDupl))

for _, item := range collection {
if duplicated := isDupl[item]; duplicated {
result = append(result, item)
isDupl[item] = false
for i := range collection {
if duplicated := isDupl[collection[i]]; duplicated {
result = append(result, collection[i])
isDupl[collection[i]] = false
}
}

Expand All @@ -196,8 +196,8 @@ func FindDuplicates[T comparable](collection []T) []T {
func FindDuplicatesBy[T any, U comparable](collection []T, iteratee func(item T) U) []T {
isDupl := make(map[U]bool, len(collection))

for _, item := range collection {
key := iteratee(item)
for i := range collection {
key := iteratee(collection[i])

duplicated, ok := isDupl[key]
if !ok {
Expand All @@ -209,11 +209,11 @@ func FindDuplicatesBy[T any, U comparable](collection []T, iteratee func(item T)

result := make([]T, 0, len(collection)-len(isDupl))

for _, item := range collection {
key := iteratee(item)
for i := range collection {
key := iteratee(collection[i])

if duplicated := isDupl[key]; duplicated {
result = append(result, item)
result = append(result, collection[i])
isDupl[key] = false
}
}
Expand Down
84 changes: 42 additions & 42 deletions intersect.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package lo

// Contains returns true if an element is present in a collection.
func Contains[T comparable](collection []T, element T) bool {
for _, item := range collection {
if item == element {
for i := range collection {
if collection[i] == element {
return true
}
}
Expand All @@ -13,8 +13,8 @@ func Contains[T comparable](collection []T, element T) bool {

// ContainsBy returns true if predicate function return true.
func ContainsBy[T any](collection []T, predicate func(item T) bool) bool {
for _, item := range collection {
if predicate(item) {
for i := range collection {
if predicate(collection[i]) {
return true
}
}
Expand All @@ -24,8 +24,8 @@ func ContainsBy[T any](collection []T, predicate func(item T) bool) bool {

// Every returns true if all elements of a subset are contained into a collection or if the subset is empty.
func Every[T comparable](collection []T, subset []T) bool {
for _, elem := range subset {
if !Contains(collection, elem) {
for i := range subset {
if !Contains(collection, subset[i]) {
return false
}
}
Expand All @@ -35,8 +35,8 @@ func Every[T comparable](collection []T, subset []T) bool {

// EveryBy returns true if the predicate returns true for all of the elements in the collection or if the collection is empty.
func EveryBy[T any](collection []T, predicate func(item T) bool) bool {
for _, v := range collection {
if !predicate(v) {
for i := range collection {
if !predicate(collection[i]) {
return false
}
}
Expand All @@ -47,8 +47,8 @@ func EveryBy[T any](collection []T, predicate func(item T) bool) bool {
// Some returns true if at least 1 element of a subset is contained into a collection.
// If the subset is empty Some returns false.
func Some[T comparable](collection []T, subset []T) bool {
for _, elem := range subset {
if Contains(collection, elem) {
for i := range subset {
if Contains(collection, subset[i]) {
return true
}
}
Expand All @@ -59,8 +59,8 @@ func Some[T comparable](collection []T, subset []T) bool {
// SomeBy returns true if the predicate returns true for any of the elements in the collection.
// If the collection is empty SomeBy returns false.
func SomeBy[T any](collection []T, predicate func(item T) bool) bool {
for _, v := range collection {
if predicate(v) {
for i := range collection {
if predicate(collection[i]) {
return true
}
}
Expand All @@ -70,8 +70,8 @@ func SomeBy[T any](collection []T, predicate func(item T) bool) bool {

// None returns true if no element of a subset are contained into a collection or if the subset is empty.
func None[T comparable](collection []T, subset []T) bool {
for _, elem := range subset {
if Contains(collection, elem) {
for i := range subset {
if Contains(collection, subset[i]) {
return false
}
}
Expand All @@ -81,8 +81,8 @@ func None[T comparable](collection []T, subset []T) bool {

// NoneBy returns true if the predicate returns true for none of the elements in the collection or if the collection is empty.
func NoneBy[T any](collection []T, predicate func(item T) bool) bool {
for _, v := range collection {
if predicate(v) {
for i := range collection {
if predicate(collection[i]) {
return false
}
}
Expand All @@ -95,13 +95,13 @@ func Intersect[T comparable](list1 []T, list2 []T) []T {
result := []T{}
seen := map[T]struct{}{}

for _, elem := range list1 {
seen[elem] = struct{}{}
for i := range list1 {
seen[list1[i]] = struct{}{}
}

for _, elem := range list2 {
if _, ok := seen[elem]; ok {
result = append(result, elem)
for i := range list2 {
if _, ok := seen[list2[i]]; ok {
result = append(result, list2[i])
}
}

Expand All @@ -118,23 +118,23 @@ func Difference[T comparable](list1 []T, list2 []T) ([]T, []T) {
seenLeft := map[T]struct{}{}
seenRight := map[T]struct{}{}

for _, elem := range list1 {
seenLeft[elem] = struct{}{}
for i := range list1 {
seenLeft[list1[i]] = struct{}{}
}

for _, elem := range list2 {
seenRight[elem] = struct{}{}
for i := range list2 {
seenRight[list2[i]] = struct{}{}
}

for _, elem := range list1 {
if _, ok := seenRight[elem]; !ok {
left = append(left, elem)
for i := range list1 {
if _, ok := seenRight[list1[i]]; !ok {
left = append(left, list1[i])
}
}

for _, elem := range list2 {
if _, ok := seenLeft[elem]; !ok {
right = append(right, elem)
for i := range list2 {
if _, ok := seenLeft[list2[i]]; !ok {
right = append(right, list2[i])
}
}

Expand All @@ -147,11 +147,11 @@ func Union[T comparable](lists ...[]T) []T {
result := []T{}
seen := map[T]struct{}{}

for _, list := range lists {
for _, e := range list {
if _, ok := seen[e]; !ok {
seen[e] = struct{}{}
result = append(result, e)
for i := range lists {
for j := range lists[i] {
if _, ok := seen[lists[i][j]]; !ok {
seen[lists[i][j]] = struct{}{}
result = append(result, lists[i][j])
}
}
}
Expand All @@ -162,9 +162,9 @@ func Union[T comparable](lists ...[]T) []T {
// Without returns slice excluding all given values.
func Without[T comparable](collection []T, exclude ...T) []T {
result := make([]T, 0, len(collection))
for _, e := range collection {
if !Contains(exclude, e) {
result = append(result, e)
for i := range collection {
if !Contains(exclude, collection[i]) {
result = append(result, collection[i])
}
}
return result
Expand All @@ -175,9 +175,9 @@ func WithoutEmpty[T comparable](collection []T) []T {
var empty T

result := make([]T, 0, len(collection))
for _, e := range collection {
if e != empty {
result = append(result, e)
for i := range collection {
if collection[i] != empty {
result = append(result, collection[i])
}
}

Expand Down
Loading
Loading