You've already received two answers which reviewed your code for efficiency and style.
You may also want to consider how Go experts write idiomatic, efficient code. Read the code for the Go standard library packages (Packages - The Go Programming Language) written by Rob (a Go language author) and Russ (the principal author of the Go gc compiler and tool chain) for examples.
Here's an example of Go code for a basic selection sort algorithm (benchmarked as peterSO):
package main
import "fmt"
// Sort Order
type SortOrder bool
const (
// Sort Order
SortAsc SortOrder = false // Ascending
SortDsc SortOrder = !SortAsc // Descending
)
// SelectionSort sorts the array a into the order specified by order.
// The selection sort algorithm is an in-place comparison sort
// with O(n*n) time complexity.
func SelectionSort(a []int, order SortOrder) {
for i, x := range a[:len(a)-1] {
k := i
for j, y := range a[i+1 : len(a)] {
// For descending order, we tolerate exchanging equal keys.
if order == (x <= y) {
// out of order
k = i + 1 + j
x = y
}
}
a[k], a[i] = a[i], x
}
}
func main() {
for _, order := range []SortOrder{SortAsc, SortDsc} {
a := []int{31, 41, 59, 26, 41, 58}
fmt.Println(a)
SelectionSort(a, order)
fmt.Println(a)
}
}
Output:
[31 41 59 26 41 58]
[26 31 41 41 58 59]
[31 41 59 26 41 58]
[59 58 41 41 31 26]
Go uses the testing package to write tests and benchmarks. These are the results for benchmarks of the various selection sort functions. Each benchmark sorts an array of 1,024 random integers from descending to ascending order and then sorts it from ascending to descending order.
$ go test -bench=. -run=NONE
BenchmarkFr00z 200 6111019 ns/op
BenchmarkRolfl 500 3168927 ns/op
BenchmarkIcza 1000 1382537 ns/op
BenchmarkPeterSO 2000 740341 ns/op
$
The delta from fr00z for rolfl, icza, and peterSO is -48.14%, -77.38%, and -87.89% respectively. The delta to peterSO from rolfl and icza is -76.64% and -46.45% respectively.
Comments should conform to godoc documentation tool standards: Godoc: documenting Go code. Provide explanatory comments that clarify, not duplicate, code.
The Go language provides facilities to hide package, function, and method implementation details from package users. For users, the sort order is not type bool
nor type func(x , y int) bool
; it's type SortOrder
. If we want to change the implementation, we can simply redefine the SortOrder
type and the implementation.
For example, go from a boolean implementation,
// Sort Order
type SortOrder bool
const (
// Sort Order
SortAsc SortOrder = false // Ascending
SortDsc SortOrder = !SortAsc // Descending
)
func SelectionSort(a []int, order SortOrder) {
// ...
if order == (x <= y) {
// ...
}
to a function implementation,
// Sort Order
type SortOrder func(x, y int) bool
// Sort Order
func SortAsc(x, y int) bool { return x >= y } // Ascending
func SortDsc(x, y int) bool { return x <= y } // Descending
func SelectionSort(a []int, order SortOrder) {
// ...
if order(x, y) {
// ...
}
Now, to use the function implementation, user packages can simply, without change, be recompiled using the Go tool chain.
The primary control structure is nested loops:
for i, x := range a[:len(a)-1] {
for j, y := range a[i+1 : len(a)] {
// ...
}
}
which use the idiomatic, efficient range form which allows the compiler to bypass some index range checks and calculate len(a)-1 once. Unless there are at least two array elements, no sort is needed. The upper limit for the outer loop is len(a)-1 not len(a).
Especially in the inner loop, avoid unnecessary address calculations, index range checks, memory accesses, and exchanges. Also, avoid inefficient comparisons.