Use slices package for most sorting#27474
Conversation
…node, neturil; use slices.Sort instead of sort.Strings
…t method for sorting
| sigs = append(sigs, sig) | ||
| } | ||
| sort.Sort(signersAscending(sigs)) | ||
| slices.SortFunc(sigs, func(a, b common.Address) bool { |
There was a problem hiding this comment.
I think you could reasonably define a Less function on common.Address. I decided not to do so in this PR, but something to consider for the maintainers.
|
|
||
| // Swap swaps the elements with indexes i and j. | ||
| func (hs hashes) Swap(i, j int) { hs[i], hs[j] = hs[j], hs[i] } | ||
| func hashesLess(a, b common.Hash) bool { |
There was a problem hiding this comment.
Similar to common.Address, maintainers might consider whether it would be reasonable to implement Less on common.Hash
|
The numbers are pretty impressive! The PR is too huge by touching lots of files. Will discuss it in our PR triage. |
|
Another variant of the benchmark: func BenchmarkSliceSort(b *testing.B) {
sizes := []int{8 /*16, 32, */, 64 /*128, 256, */, 512 /*1024, 2048, */, 4096, 8192}
for _, size := range sizes {
src := make([]byte, size)
rand.Read(src)
data := make([]byte, size)
b.Run(fmt.Sprintf("slices.Sort size=%d", size),
func(b *testing.B) {
for i := 0; i < b.N; i++ {
copy(data, src)
slices.Sort(data)
}
},
)
b.Run(fmt.Sprintf("slices.SortFunc size=%d", size),
func(b *testing.B) {
for i := 0; i < b.N; i++ {
copy(data, src)
//slices.Sort(data)
slices.SortFunc(data, func(a, b byte) bool {
return a < b
})
}
},
)
b.Run(fmt.Sprintf("sort.Slice size=%d", size),
func(b *testing.B) {
for i := 0; i < b.N; i++ {
copy(data, src)
sort.Slice(data, func(i, j int) bool {
return data[i] < data[j]
})
}
},
)
}
}Results This is worth pursuing, but perhaps it would be better to bite off smaller chunks. We've done so before on larger prs that touch everything (e.g. when converting from the form |
|
@holiman Sure I'll close this PR and open a bunch of smaller ones that only touch 1 or 2 packages |
This PR makes changes many, but not all, uses of sorting functions from the
sortpackage to use theslicespackage instead.sort.Sortrelies onsort.Interface, which often requires implementing structs whose sole purpose is to implement this interface. This change allows for the removal of several such structs (e.g.type authors []stringinbuild/update-license.go)sort.Sliceuses reflection internally, which is slow. Usingslices.Sortis faster. This benchmark:gives these results on my machine:
I didn't replace all usage of
sort.Sort. Namely, I left it in places where:sort.Interfacealso implementsheap.Interface(so it can't be removed anyway.)capacitySortineth/protocols/snap/sync.go)