perf: preallocate result slices in Difference (#830)

Difference previously initialized left and right as empty slice
literals (Slice{}), causing repeated grow-and-copy allocations
as elements were appended.

Now preallocates with make(Slice, 0, len(listN)) to avoid
unnecessary reallocations.
This commit is contained in:
Samuel Berthe
2026-03-05 21:15:05 +01:00
committed by GitHub
parent e82e7f5d7d
commit 1f669cbc2d
2 changed files with 24 additions and 2 deletions
+22
View File
@@ -353,3 +353,25 @@ func BenchmarkFilterTakeVsFilterAndTake(b *testing.B) {
}
})
}
func BenchmarkDifference(b *testing.B) {
for _, n := range lengths {
ints1 := genSliceInt(n)
ints2 := genSliceInt(n)
b.Run(fmt.Sprintf("ints_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _ = lo.Difference(ints1, ints2)
}
})
}
for _, n := range lengths {
strs1 := genSliceString(n)
strs2 := genSliceString(n)
b.Run(fmt.Sprintf("strings_%d", n), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _ = lo.Difference(strs1, strs2)
}
})
}
}
+2 -2
View File
@@ -207,8 +207,8 @@ func IntersectBy[T any, K comparable, Slice ~[]T](transform func(T) K, lists ...
// The second value is the collection of elements absent from list1.
// Play: https://go.dev/play/p/pKE-JgzqRpz
func Difference[T comparable, Slice ~[]T](list1, list2 Slice) (Slice, Slice) {
left := Slice{}
right := Slice{}
left := make(Slice, 0, len(list1))
right := make(Slice, 0, len(list2))
seenLeft := Keyify(list1)
seenRight := Keyify(list2)