Skip to content

strings, x/exp/slices: strings.Compare is more useful than its docs say, but also slow #58142

Closed
@greatroar

Description

@greatroar

What version of Go are you using (go version)?

go version devel go1.21-4f467f1082 Wed Jan 25 21:16:32 2023 +0000 linux/amd64

What did you do?

I benchmarked two binary searches on an array of strings:

sort.Search(len(strs), func(i int) bool { return key <= strs[i] })
slices.BinarySearchFunc(strs, key, strings.Compare)

Turns out the former can be significantly faster. Seeing how strings.Compare is implemented, I get why:

// Compare returns an integer comparing two strings lexicographically.
// The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
//
// Compare is included only for symmetry with package bytes.
// It is usually clearer and always faster to use the built-in
// string comparison operators ==, <, >, and so on.
func Compare(a, b string) int {
// NOTE(rsc): This function does NOT call the runtime cmpstring function,
// because we do not want to provide any performance justification for
// using strings.Compare. Basically no one should use strings.Compare.
// As the comment above says, it is here only for symmetry with package bytes.
// If performance is important, the compiler should be changed to recognize
// the pattern so that all code doing three-way comparisons, not just code
// using strings.Compare, can benefit.
if a == b {
return 0
}
if a < b {
return -1
}
return +1
}

Should the decision to not optimize strings.Compare be reconsidered? Even if not, should its comments be changed to not recommend against its use? Because it appears to me as the sane way to work with strings and x/exp/slices.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DocumentationIssues describing a change to documentation.FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions