Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup field sorting #77

Merged
merged 1 commit into from
Dec 19, 2024
Merged

Cleanup field sorting #77

merged 1 commit into from
Dec 19, 2024

Conversation

dsnet
Copy link
Collaborator

@dsnet dsnet commented Dec 19, 2024

Use of cmp.Or with a series of compare function is more readable as it clearly which ordering dimension takes precedence.

Use of cmp.Or with a series of compare function is more readable
as it clearly which ordering dimension takes precedence.
return 0 // TODO(https://go.dev/issue/61643): Compare bools better.
}
slices.SortStableFunc(allFields, func(x, y structField) int {
return cmp.Or(
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorting multiple dimensions has now become my favorite use of cmp.Or

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow never thought of this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this particular case it doesn't seem to be a big deal, but isn't the use of cmp.Or causing all arguments to all be computed upfront? in the old implementation, if e.g. the names didn't match, then you didn't have to run cmp.Compare on the index lengths.

again in this case I doubt it's a noticeable difference, but if you have a cmp.Or with five chained string comparisons, I bet it can matter if often it's the first comparison that would make the other ones unnecessary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only happens once per type and then the result is cached. I'll take readability over performance in this case.

@@ -544,3 +536,15 @@ func consumeTagOption(in string) (string, int, error) {
func isLetterOrDigit(r rune) bool {
return r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r)
}

// boolsCompare compares x and y, ordering false before true.
func boolsCompare(x, y bool) int {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still sad the stdlib or language still doesn't provide a first-class way to compare bools.

At Tailscale we added a package just for this: https://pkg.go.dev/tailscale.com/types/bools#Compare

@@ -544,3 +536,15 @@ func consumeTagOption(in string) (string, int, error) {
func isLetterOrDigit(r rune) bool {
return r == '_' || unicode.IsLetter(r) || unicode.IsNumber(r)
}

// boolsCompare compares x and y, ordering false before true.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth keeping the reference to https://go.dev/issue/61643 here so we don't forget that there is a declined proposal for this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The challenge is there's been so many bool-to-int or compare-bools proposals. 61643 isn't exactly unique. I think a standalone helper that is equivalent to bools.Compare will be useful for static analysis to one-day prove how often this is used rather than a reference to the issue.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's okay, I'm sure the next bool-to-int proposal will get approved 😉

@dsnet dsnet merged commit 8aae9ab into master Dec 19, 2024
8 checks passed
@dsnet dsnet deleted the fields-cleanup branch December 19, 2024 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants