Go中切片排序的意外基准结果

Go中切片排序的意外基准结果,go,benchmarking,Go,Benchmarking,我刚开始学习golang,并决定实现一些基本排序算法(冒泡排序、选择排序和插入排序),以尝试使用包、切片和测试基础设施 以下是实现: package child_sort func SortBubble(xs []int) { for i := range xs { swapped := false for j := 1; j < len(xs)-i; j++ { if xs[j-1] > xs[j] {

我刚开始学习golang,并决定实现一些基本排序算法(冒泡排序、选择排序和插入排序),以尝试使用包、切片和测试基础设施

以下是实现:

package child_sort

func SortBubble(xs []int) {
    for i := range xs {
        swapped := false
        for j := 1; j < len(xs)-i; j++ {
            if xs[j-1] > xs[j] {
                xs[j-1], xs[j] = xs[j], xs[j-1]
                swapped = true
            }
        }
        if !swapped {
            break
        }
    }
}

func SortSelection(xs []int) {
    for i := range xs {
        min_i := i
        for j := i + 1; j < len(xs); j++ {
            if xs[j] < xs[min_i] {
                min_i = j
            }
        }
        if min_i != i {
            xs[i], xs[min_i] = xs[min_i], xs[i]
        }
    }
}

func SortInsertion(xs []int) {
    for i := 1; i < len(xs); i++ {
        for j := i; j > 0; j-- {
            if xs[j] < xs[j-1] {
                xs[j], xs[j-1] = xs[j-1], xs[j]
            }
        }
    }
}
让我烦恼的是,选择排序几乎立即运行,并且产生零分配。如果我减小数组的大小,其他排序算法也会发生同样的情况。反之亦然,也就是说,如果我增加大小,选择排序就会开始正常运行

以下是测试文件:

package child_sort

import (
    "math/rand"
    "testing"
    "time"
)

func generate(size int, min, max int) []int {
    rand.Seed(time.Now().UTC().UnixNano())
    var xs = make([]int, size, size)
    for i := range xs {
        xs[i] = min + rand.Intn(max-min)
    }
    return xs
}

func TestSortBubble(t *testing.T) {
    xs := []int{9, 8, 7, 6, 5}
    ys := []int{5, 6, 7, 8, 9}
    SortBubble(xs)
    for i, v := range xs {
        if v != ys[i] {
            t.Errorf("fail")
        }
    }
}

func TestSortSelection(t *testing.T) {
    xs := []int{1, 2, 9, 6, 2}
    ys := []int{1, 2, 2, 6, 9}
    SortSelection(xs)
    for i, v := range xs {
        if v != ys[i] {
            t.Errorf("fail")
        }
    }
}

func TestSortInsertion(t *testing.T) {
    xs := []int{1, 2, 9, 6, 2}
    ys := []int{1, 2, 2, 6, 9}
    SortInsertion(xs)
    for i, v := range xs {
        if v != ys[i] {
            t.Errorf("fail")
        }
    }
}

func BenchmarkBubble(b *testing.B) {
    xs := generate(10000, -100, 100)
    /* b.ResetTimer() */
    SortBubble(xs)
}

func BenchmarkSelection(b *testing.B) {
    xs := generate(10000, -100, 100)
    /* b.ResetTimer() */
    SortSelection(xs)
}

func BenchmarkInsertion(b *testing.B) {
    xs := generate(10000, -100, 100)
    /* b.ResetTimer() */
    SortInsertion(xs)
}

观察到的效果与排序代码、切片或其他内容无关。您只是没有正确地使用
b testing.b
:您应该执行代码
b.N

看看标准排序包是如何实现其基准的:

package child_sort

import (
    "math/rand"
    "testing"
    "time"
)

func generate(size int, min, max int) []int {
    rand.Seed(time.Now().UTC().UnixNano())
    var xs = make([]int, size, size)
    for i := range xs {
        xs[i] = min + rand.Intn(max-min)
    }
    return xs
}

func TestSortBubble(t *testing.T) {
    xs := []int{9, 8, 7, 6, 5}
    ys := []int{5, 6, 7, 8, 9}
    SortBubble(xs)
    for i, v := range xs {
        if v != ys[i] {
            t.Errorf("fail")
        }
    }
}

func TestSortSelection(t *testing.T) {
    xs := []int{1, 2, 9, 6, 2}
    ys := []int{1, 2, 2, 6, 9}
    SortSelection(xs)
    for i, v := range xs {
        if v != ys[i] {
            t.Errorf("fail")
        }
    }
}

func TestSortInsertion(t *testing.T) {
    xs := []int{1, 2, 9, 6, 2}
    ys := []int{1, 2, 2, 6, 9}
    SortInsertion(xs)
    for i, v := range xs {
        if v != ys[i] {
            t.Errorf("fail")
        }
    }
}

func BenchmarkBubble(b *testing.B) {
    xs := generate(10000, -100, 100)
    /* b.ResetTimer() */
    SortBubble(xs)
}

func BenchmarkSelection(b *testing.B) {
    xs := generate(10000, -100, 100)
    /* b.ResetTimer() */
    SortSelection(xs)
}

func BenchmarkInsertion(b *testing.B) {
    xs := generate(10000, -100, 100)
    /* b.ResetTimer() */
    SortInsertion(xs)
}