Go语言 常见数据结构性能测试

abv123456789 · · 1217 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

在开发过程中,我们总是在设计不同的数据结构和不同的算法对数据进行组织和存取,有些场合我们可以用硬编码或者代码生成器来生成一组函数按条件返回数据,另外一些场合我们可以把数据存储在slice当中,需要查找时就遍历查找,又或者有的场合我们可以用map存储数据,用key来索引数据。这几种数据存取方式在不同数据量的情况下,性能消耗是怎么样的呢?下面做个对比实验。

我们知道go的map数据量不管大小都能保证固定的读取时间,而slice和硬编码肯定无法应对大数据量,所以这里不做大数据量的实验,只做小数据量的实验。

实验代码(github):

package labs06

import "testing"

type BigStruct struct {
    C01 int
    C02 int
    C03 int
    C04 int
    C05 int
    C06 int
    C07 int
    C08 int
    C09 int
    C10 int
    C11 int
    C12 int
    C13 int
    C14 int
    C15 int
    C16 int
    C17 int
    C18 int
    C19 int
    C20 int
    C21 int
    C22 int
    C23 int
    C24 int
    C25 int
    C26 int
    C27 int
    C28 int
    C29 int
    C30 int
}

func Loop1(a []BigStruct) int {
    for i := 0; i < len(a); i++ {
        if a[i].C30 == 3 {
            return i
        }
    }

    return -1
}

func Loop2(a []BigStruct) int {
    for i := len(a) - 1; i >= 0; i-- {
        if a[i].C30 == 1 {
            return i
        }
    }

    return -1
}

func Loop3(a map[int]BigStruct) int {
    return a[2].C30
}

func Loop4(a []*BigStruct) int {
    for i, x := range a {
        if x.C30 == 3 {
            return i
        }
    }

    return -1
}

func Loop5(a []BigStruct) int {
    switch {
    case a[0].C01 == 3:
        return 0
    case a[1].C01 == 3:
        return 1
    case a[2].C01 == 3:
        return 2
    }

    return -1
}

func Benchmark_Loop1(b *testing.B) {
    var a = make([]BigStruct, 3)

    a[0].C30 = 1
    a[1].C30 = 2
    a[2].C30 = 3

    for i := 0; i < b.N; i++ {
        Loop1(a)
    }
}

func Benchmark_Loop2(b *testing.B) {
    var a = make([]BigStruct, 3)

    a[0].C30 = 1
    a[1].C30 = 2
    a[2].C30 = 3

    for i := 0; i < b.N; i++ {
        Loop2(a)
    }
}

func Benchmark_Loop3(b *testing.B) {
    var a = make(map[int]BigStruct, 3)

    a[0] = BigStruct{C30: 1}
    a[1] = BigStruct{C30: 2}
    a[2] = BigStruct{C30: 3}

    for i := 0; i < b.N; i++ {
        Loop3(a)
    }
}

func Benchmark_Loop4(b *testing.B) {
    var a = make([]*BigStruct, 3)

    a[0] = &BigStruct{C30: 1}
    a[1] = &BigStruct{C30: 2}
    a[2] = &BigStruct{C30: 3}

    for i := 0; i < b.N; i++ {
        Loop4(a)
    }
}

func Benchmark_Loop5(b *testing.B) {
    var a = make([]BigStruct, 3)

    a[0].C30 = 1
    a[1].C30 = 2
    a[2].C30 = 3

    for i := 0; i < b.N; i++ {
        Loop5(a)
    }
}

试验结果:

dada-imac:labs dada$ go test -test.bench="." labs06
testing: warning: no tests to run
PASS
Benchmark_Loop1    500000000             5.73 ns/op
Benchmark_Loop2    500000000             5.72 ns/op
Benchmark_Loop3    50000000              68.0 ns/op
Benchmark_Loop4    500000000             4.92 ns/op
Benchmark_Loop5    500000000             4.40 ns/op
ok      labs06  15.970s    

结论:硬编码 < 指针slice的range循环 < for循环,但是量级是一样的,看情况用。但是map差了一个量级,小数据量尽量少用。


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:abv123456789

查看原文:Go语言 常见数据结构性能测试

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1217 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传