或者根据阵列大小突然减速

oli*_*666 3 arrays benchmarking go

我写了一个简单的程序,它包含了一个巨大的切片中包含的所有值.当我使用10倍大的切片时,我预计会有10倍的性能下降.但是,在执行提供的测试时,存在巨大的性能差距.程序输出如下:

oadam@oadam-Latitude-E6510:~/$ go test -bench .
testing: warning: no tests to run
PASS
BenchmarkLittle 2000000000           0.11 ns/op
BenchmarkBig           1    2417869962 ns/op
ok      _/home/oadam/   5.048s
Run Code Online (Sandbox Code Playgroud)

和代码

package main

import (
    "math/rand"
    "testing"
)

const (
    little = 5000000
    big    = 50000000
)

var a = make([]uint32, big)

func benchOR(b *testing.B, l int) {
    for i := 0; i < l; i++ {
        a[i] = rand.Uint32()
    }

    var result uint32
    for i := 0; i < l; i++ {
        result |= a[i]
    }
}

func BenchmarkLittle(b *testing.B) {
    benchOR(b, little)
}

func BenchmarkBig(b *testing.B) {
    benchOR(b, big)
}
Run Code Online (Sandbox Code Playgroud)

编辑:必须是go test -bench中的一个bug.使用手动计时我不重现

package main

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

const (
    little = 5000000
    big    = 50000000
)

var a = make([]uint32, big)

func initA(l int) {
    for i := 0; i < l; i++ {
        a[i] = rand.Uint32()
    }
}

func test(l int) uint32 {
    var result uint32
    for i := 0; i < l; i++ {
        result |= a[i]
    }
    return result
}

func main() {
    initA(little)
    var before = time.Now()
    test(little)
    log.Println(time.Since(before))

    initA(big)
    var before2 = time.Now()
    test(big)
    log.Println(time.Since(before2))

}
Run Code Online (Sandbox Code Playgroud)

Eva*_*haw 5

问题是你没有使用b.N,它会告诉你运行基准测试的次数.此外,如果您只想对ORing进行基准测试,您可能只需要初始化一次数组,或者至少调用一次,b.ResetTimer()这样就不会计算初始化.

这是我最终得到的结果,它给出了预期的结果:

package main

import (
    "math/rand"
    "testing"
)

const (
    little = 5000000
    big    = 50000000
)

var a = make([]uint32, big)

func init() {
    for i := 0; i < big; i++ {
        a[i] = rand.Uint32()
    }
}

func benchOR(b *testing.B, l int) {
    var result uint32
    for _, u := range a[:l] {
        result |= u
    }
}

func BenchmarkLittle(b *testing.B) {
    for i := 0; i < b.N; i++ {
        benchOR(b, little)
    }
}

func BenchmarkBig(b *testing.B) {
    for i := 0; i < b.N; i++ {
        benchOR(b, big)
    }
}
Run Code Online (Sandbox Code Playgroud)

我的结果:

BenchmarkLittle      500       3222064 ns/op
BenchmarkBig          50      32268023 ns/op
Run Code Online (Sandbox Code Playgroud)