Fix FirstUniqueStrings after conversion to generics
The conversion of FirstUniqueStrings to be implemented on top of the generic firstUnique accidentally used a different threshold to switch from the list implementation to the map implementation. Modify the threshold of firstUnique to match the old value from FirstUniqueStrings now that it doesn't have the reflection overhead. While we're at it, also make firstUnique make a copy of the list, and make FirstUniqueStrings a pure wrapper around firstUnique. Test: BenchmarkFirstUniqueStrings Change-Id: Icc2febea663142c508ff2e4be65a8a68121631d5
This commit is contained in:
@@ -25,12 +25,12 @@ import (
|
||||
)
|
||||
|
||||
// CopyOf returns a new slice that has the same contents as s.
|
||||
func CopyOf(s []string) []string {
|
||||
func CopyOf[T any](s []T) []T {
|
||||
// If the input is nil, return nil and not an empty list
|
||||
if s == nil {
|
||||
return s
|
||||
}
|
||||
return append([]string{}, s...)
|
||||
return append([]T{}, s...)
|
||||
}
|
||||
|
||||
// Concat returns a new slice concatenated from the two input slices. It does not change the input
|
||||
@@ -278,22 +278,25 @@ func RemoveFromList(s string, list []string) (bool, []string) {
|
||||
}
|
||||
|
||||
// FirstUniqueStrings returns all unique elements of a slice of strings, keeping the first copy of
|
||||
// each. It modifies the slice contents in place, and returns a subslice of the original slice.
|
||||
// each. It does not modify the input slice.
|
||||
func FirstUniqueStrings(list []string) []string {
|
||||
// Do not moodify the input in-place, operate on a copy instead.
|
||||
list = CopyOf(list)
|
||||
// 128 was chosen based on BenchmarkFirstUniqueStrings results.
|
||||
if len(list) > 128 {
|
||||
return firstUnique(list)
|
||||
}
|
||||
return firstUnique(list)
|
||||
}
|
||||
|
||||
// firstUnique returns all unique elements of a slice, keeping the first copy of each. It
|
||||
// modifies the slice contents in place, and returns a subslice of the original slice.
|
||||
// does not modify the input slice.
|
||||
func firstUnique[T comparable](slice []T) []T {
|
||||
// 4 was chosen based on Benchmark_firstUnique results.
|
||||
if len(slice) > 4 {
|
||||
// Do not modify the input in-place, operate on a copy instead.
|
||||
slice = CopyOf(slice)
|
||||
return firstUniqueInPlace(slice)
|
||||
}
|
||||
|
||||
// firstUniqueInPlace returns all unique elements of a slice, keeping the first copy of
|
||||
// each. It modifies the slice contents in place, and returns a subslice of the original
|
||||
// slice.
|
||||
func firstUniqueInPlace[T comparable](slice []T) []T {
|
||||
// 128 was chosen based on BenchmarkFirstUniqueStrings results.
|
||||
if len(slice) > 128 {
|
||||
return firstUniqueMap(slice)
|
||||
}
|
||||
return firstUniqueList(slice)
|
||||
|
Reference in New Issue
Block a user