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 <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/slices/slices.go b/slices/slices.go
index 0c756c4..ff8b5d8 100644
--- a/slices/slices.go
+++ b/slices/slices.go
@@ -193,7 +193,7 @@
 // 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 @@
 
 // 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 367dcf1..35ccad5 100644
--- a/slices/slices_test.go
+++ b/slices/slices_test.go
@@ -497,30 +497,37 @@
 }
 
 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 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)