代码和性能的顺序

Jsm*_*ith 2 performance benchmarking struct go slice

我想找到哪个更快:struct vs array.所以我编写了一个GO代码,在其中我将4个int值(1,2,3和4)写入结构的成员,然后写入长度为4的数组.我试图找到写入所需的时间.

案例1:首先,我将值写入结构,然后写入数组.在这里,我发现数组比结构更快.

package main

import (
    "fmt"
    "time"
)

type abc struct {
    a, b, c, d int
}

func main() {

    var obj abc

    t1 := time.Now()
    obj.a = 1
    obj.b = 2
    obj.c = 3
    obj.d = 4
    t2 := time.Since(t1)

    fmt.Println("Struct access time: : ", t2)

    a := make([]int, 4)
    t3 := time.Now()
    a[0] = 1
    a[1] = 2
    a[2] = 3
    a[3] = 4
    t4 := time.Since(t3)

    fmt.Println("Array access time: : ", t4)

}
Run Code Online (Sandbox Code Playgroud)

案例2:其次,我将值写入数组,然后写入结构.在这里,我发现结构比数组更快.

package main

import (
    "fmt"
    "time"
)

type abc struct {
    a, b, c, d int
}

func main() {

    var obj abc

    a := make([]int, 4)
    t3 := time.Now()
    a[0] = 1
    a[1] = 2
    a[2] = 3
    a[3] = 4
    t4 := time.Since(t3)

    fmt.Println("Array access time: : ", t4)

    t1 := time.Now()
    obj.a = 1
    obj.b = 2
    obj.c = 3
    obj.d = 4
    t2 := time.Since(t1)

    fmt.Println("Struct access time: : ", t2)

}
Run Code Online (Sandbox Code Playgroud)

为什么性能取决于我先写的内容​​?我写的第一个看起来比较慢.为什么会这样?

icz*_*cza 11

第一次运行任何代码可能具有一些(显着)开销,例如可能加载相关代码,许多事情可能被推迟直到需要它们(例如内部缓冲区).再次运行相同的东西可能会花费更少的时间,差异甚至可能是几个数量级.

无论何时想要测量执行时间,都应该多次运行,测量多次运行的执行时间,并计算平均时间.出于上述原因,从计算中排除第一(一些)运行也是一个好主意.

在Go中,最好和最简单的方法是使用测试文件和基准测试功能.阅读包文档以testing获取更多详细信息和示例.

您的案例可以像这样进行基准测试:

package main

import "testing"

type abc struct {
    a, b, c, d int
}

func BenchmarkSlice(b *testing.B) {
    a := make([]int, 4)
    for i := 0; i < b.N; i++ {
        a[0] = 1
        a[1] = 2
        a[2] = 3
        a[3] = 4
    }
}

func BenchmarkStruct(b *testing.B) {
    a := abc{}
    for i := 0; i < b.N; i++ {
        a.a = 1
        a.b = 2
        a.c = 3
        a.d = 4
    }
}
Run Code Online (Sandbox Code Playgroud)

将其保存到文件中something_test.go,运行它go test -bench ..输出:

BenchmarkSlice-4        2000000000           1.24 ns/op
BenchmarkStruct-4       2000000000           0.31 ns/op
Run Code Online (Sandbox Code Playgroud)

您可以看到使用结构的速度大约快4倍.如果重新排序基准函数,您将获得类似(非常接近)的结果.

  • 我只是阅读生成的代码。由于编译器确切知道切片的大小,因此可以避免边界检查。实际发生的情况是,完全消除了对结构的写入,我认为是通过消除死区存储来实现的,而对切片的写入却没有。将结构设为全局会禁用死存储消除,并且两者的性能完全相同。 (2认同)