【问题标题】:Benchmarking bad results对不良结果进行基准测试
【发布时间】:2017-11-28 06:06:09
【问题描述】:

所以我使用并发实现了快速排序算法(也没有实现)。现在我想比较一下时代。我是这样写的:

func benchmarkConcurrentQuickSort(size int, b *testing.B) {
    A := RandomArray(size)
    var wg sync.WaitGroup
    b.ResetTimer()
    ConcurrentQuicksort(A, 0, len(A)-1, &wg)
    wg.Wait()
}

func BenchmarkConcurrentQuickSort500(b *testing.B) {
    benchmarkConcurrentQuickSort(500, b)
}
func BenchmarkConcurrentQuickSort1000(b *testing.B) {
    benchmarkConcurrentQuickSort(1000, b)
}
func BenchmarkConcurrentQuickSort5000(b *testing.B) {
    benchmarkConcurrentQuickSort(5000, b)
}
func BenchmarkConcurrentQuickSort10000(b *testing.B) {
    benchmarkConcurrentQuickSort(10000, b)
}
func BenchmarkConcurrentQuickSort20000(b *testing.B) {
    benchmarkConcurrentQuickSort(20000, b)
}
func BenchmarkConcurrentQuickSort1000000(b *testing.B) {
    benchmarkConcurrentQuickSort(1000000, b)
}

结果是这样的:

C:\projects\go\src\github.com\frynio\mysort>go test -bench=.
BenchmarkConcurrentQuickSort500-4               2000000000               0.00 ns/op
BenchmarkConcurrentQuickSort1000-4              2000000000               0.00 ns/op
BenchmarkConcurrentQuickSort5000-4              2000000000               0.00 ns/op
BenchmarkConcurrentQuickSort10000-4             2000000000               0.00 ns/op
BenchmarkConcurrentQuickSort20000-4             2000000000               0.00 ns/op
BenchmarkConcurrentQuickSort1000000-4                 30          49635266 ns/op
PASS
ok      github.com/frynio/mysort        8.342s

我可以相信最后一个,但我绝对认为排序 500 个元素的数组需要比 1ns 更长的时间。我究竟做错了什么?我很确定RandomArray 返回所需大小的数组,正如我们在上一个基准测试中看到的那样。为什么会打印出 0.00 ns?

func RandomArray(n int) []int {
    a := []int{}
    for i := 0; i < n; i++ {
        a = append(a, rand.Intn(500))
    }
    return a
}

// ConcurrentPartition - ConcurrentQuicksort function for partitioning the array (randomized choice of a pivot)
func ConcurrentPartition(A []int, p int, r int) int {
    index := rand.Intn(r-p) + p
    pivot := A[index]
    A[index] = A[r]
    A[r] = pivot
    x := A[r]
    j := p - 1
    i := p
    for i < r {
        if A[i] <= x {
            j++
            tmp := A[j]
            A[j] = A[i]
            A[i] = tmp
        }
        i++
    }
    temp := A[j+1]
    A[j+1] = A[r]
    A[r] = temp
    return j + 1
}

// ConcurrentQuicksort - a concurrent version of a quicksort algorithm
func ConcurrentQuicksort(A []int, p int, r int, wg *sync.WaitGroup) {
    if p < r {
        q := ConcurrentPartition(A, p, r)
        wg.Add(2)
        go func() {
            ConcurrentQuicksort(A, p, q-1, wg)
            wg.Done()
        }()
        go func() {
            ConcurrentQuicksort(A, q+1, r, wg)
            wg.Done()
        }()
    }
}

【问题讨论】:

  • 您确定RandomArray()ConcurrentQuicksort() 是正确的吗?您应该发布重现问题所需的完整代码;见minimal reproducible example
  • 编辑了代码,RandomArray()ConcurrentQuicksort() 都经过了随机500000 大小的测试;

标签: go benchmarking


【解决方案1】:

Package testing

一个示例基准函数如下所示:

func BenchmarkHello(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fmt.Sprintf("hello")
    }
}

基准函数必须运行目标代码 b.N 次。期间 基准执行,b.N被调整直到基准函数 持续时间足够长,可以可靠地计时。

我在您的代码中没有看到基准循环。试试

func benchmarkConcurrentQuickSort(size int, b *testing.B) {
    A := RandomArray(size)
    var wg sync.WaitGroup
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        ConcurrentQuicksort(A, 0, len(A)-1, &wg)
        wg.Wait()
    }
}

输出:

BenchmarkConcurrentQuickSort500-4              10000        122291 ns/op
BenchmarkConcurrentQuickSort1000-4              5000        221154 ns/op
BenchmarkConcurrentQuickSort5000-4              1000       1225230 ns/op
BenchmarkConcurrentQuickSort10000-4              500       2568024 ns/op
BenchmarkConcurrentQuickSort20000-4              300       5808130 ns/op
BenchmarkConcurrentQuickSort1000000-4              1    1371751710 ns/op

【讨论】:

  • 是的,我确实知道了,但我需要在循环中使用A := RandomArray(size),否则它将对排序后的数组进行排序,这很糟糕。如果我试试这个,它会说:BenchmarkConcurrentQuickSort10000-4 *** Test killed: ran too long (10m0s). FAIL github.com/frynio/mysort 600.023s
猜你喜欢
  • 1970-01-01
  • 2012-02-02
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 2017-12-30
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多