Skip to content

proposal: sort: return equal values in non-deterministic order #13884

@rsc

Description

@rsc

Crazy idea, but what if sort.Sort randomly permuted its input a bit before starting?

Go 1.6 has a different sort.Sort than Go 1.5 and I've seen at least a dozen test failures at Google that were implicitly depending on the old algorithm. The usual scenario is that you sort a slice of structs by one field in the struct. If there are entries with that field equal but others unequal and you expect a specific order for the structs at the end, you are depending on sort.Sort's algorithm. A later sort.Sort might make a different choice and produce a different order. This makes programs not portable from one version of Go to another, much like map hash differences used to make programs not portable from one architecture to another. We solved maps by randomizing the iteration order a bit. In the map case it's not a full permutation, but just enough variation to make tests obviously flaky.

I wonder if we should do the same for sort.Sort. It would only take N swaps to shuffle things quite well, and we already use N*log(N) swaps, so N*(log(N)+1) is not likely to be noticed. That would also protect a bit against malicious inputs.

It would surprise people, especially people who think sort.Sort == sort.Stable. But the rationale is that it's better to surprise them the first time they run the code instead of however many Go releases later.

/cc @robpike, @griesemer, @ianlancetaylor, @aclements, @dr2chase

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions