diff --git a/slices/slices.go b/slices/slices.go index 0c756c46c..ff8b5d842 100644 --- a/slices/slices.go +++ b/slices/slices.go @@ -193,7 +193,7 @@ func Clone[S ~[]E, E any](s S) S { // This is like the uniq command found on Unix. // Compact modifies the contents of the slice s; it does not create a new slice. func Compact[S ~[]E, E comparable](s S) S { - if len(s) == 0 { + if len(s) < 2 { return s } i := 1 @@ -210,7 +210,7 @@ func Compact[S ~[]E, E comparable](s S) S { // CompactFunc is like Compact but uses a comparison function. func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S { - if len(s) == 0 { + if len(s) < 2 { return s } i := 1 diff --git a/slices/slices_test.go b/slices/slices_test.go index 367dcf1cd..35ccad51f 100644 --- a/slices/slices_test.go +++ b/slices/slices_test.go @@ -497,30 +497,37 @@ func TestClone(t *testing.T) { } var compactTests = []struct { + name string s []int want []int }{ { + "nil", nil, nil, }, { + "one", []int{1}, []int{1}, }, { + "sorted", []int{1, 2, 3}, []int{1, 2, 3}, }, { + "1 item", []int{1, 1, 2}, []int{1, 2}, }, { + "unsorted", []int{1, 2, 1}, []int{1, 2, 1}, }, { + "many", []int{1, 2, 2, 3, 3, 4}, []int{1, 2, 3, 4}, }, @@ -535,6 +542,20 @@ func TestCompact(t *testing.T) { } } +func BenchmarkCompact(b *testing.B) { + for _, c := range compactTests { + b.Run(c.name, func(b *testing.B) { + ss := make([]int, 0, 64) + for k := 0; k < b.N; k++ { + ss = ss[:0] + ss = append(ss, c.s...) + _ = Compact(ss) + } + }) + } + +} + func TestCompactFunc(t *testing.T) { for _, test := range compactTests { copy := Clone(test.s)