From d0897a79cd3779a8307f427940c2b02b326d9f52 Mon Sep 17 00:00:00 2001 From: siarhei Date: Thu, 10 Nov 2022 07:38:56 +0000 Subject: [PATCH] slices: return quickly for Compact of one element Change-Id: I993c34b2cedc18da3500d3ddcbdeeb6bbc73d10f GitHub-Last-Rev: 1620ea09e9518260e03d909734d9f6fbad5122de GitHub-Pull-Request: golang/exp#46 Reviewed-on: https://go-review.googlesource.com/c/exp/+/448878 Auto-Submit: Keith Randall Reviewed-by: Keith Randall Reviewed-by: Keith Randall Run-TryBot: Keith Randall Reviewed-by: Ian Lance Taylor TryBot-Result: Gopher Robot --- slices/slices.go | 4 ++-- slices/slices_test.go | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) 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)