0

数据查询用Slice还是Map

 2 years ago
source link: https://dafengge0913.github.io/slice-or-map-for-search/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

数据查询用Slice还是Map

如果有一些不重复的数据需要记录,并且用来查询某一数据是否存在,可以有两种做法:
1、存在slice中,每次查询时遍历slice,如果查到数据则退出遍历,时间复杂度是O(n)。
2、存在一个集合中,golang中可以使用map的key来保存,每次直接判断该数据是否存在,时间复杂度是O(1)。

从时间复杂度上面来看,使用map是有明显优势的,但是如果数据量较小,O(1)可能并没有O(n)的速度快,那么应该如何选择呢?
下面写了一个性能测试:

package main

import (
	"testing"
)

var s []int
var m map[int]struct{}

func init() {
	num := 10
	s = make([]int, num)
	m = make(map[int]struct{}, num)
	for i := 0; i < num; i++ {
		s[i] = i
		m[i] = struct{}{}
	}
}

func BenchmarkSlice(b *testing.B) {
	size := len(s)
	for i := 0; i < b.N; i++ {
		n := i % size
		for k := 0; k < len(s); k++ {
			if s[k] == n {
				break
			}
		}
	}
}

func BenchmarkMap(b *testing.B) {
	size := len(s)
	for i := 0; i < b.N; i++ {
		n := i % size
		_ = m[n]
	}
}

测试结果:
num = 1:
BenchmarkSlice-4 200000000 9.20 ns/op
BenchmarkMap-4 100000000 15.3 ns/op

num = 10:
BenchmarkSlice-4 100000000 11.2 ns/op
BenchmarkMap-4 100000000 16.7 ns/op

num = 20:
BenchmarkSlice-4 100000000 14.9 ns/op
BenchmarkMap-4 100000000 16.7 ns/op

num = 30:
BenchmarkSlice-4 100000000 18.9 ns/op
BenchmarkMap-4 100000000 16.8 ns/op

num = 100:
BenchmarkSlice-4 50000000 40.0 ns/op
BenchmarkMap-4 100000000 17.7 ns/op

根据测试结果可以发现,map随着数据量的增多,对性能产生的影响比较小,在大量数据的情况下性能有明显优势,在无法估计数据量的情况下,map的适用范围更广。如果是性能关键点并且数据量较小,可以考虑使用slice。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK