当前位置:   article > 正文

Golang 几种判断 Contains/包含 的性能比较_go contains

go contains

Go 语言判断元素列表里是否包含某个元素,通常有两种方法:遍历列表、转为map后判断是否包含key。

遍历列表

[]string 遍历判断

func ContainsStr(slice []string, element string) bool {
	for _, e := range slice {
		if e == element {
			return true
		}
	}

	return false
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

[]int 遍历判断

func ContainsInt(slice []int, element int) bool {
	for _, e := range slice {
		if e == element {
			return true
		}
	}

	return false
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

如果 slice 是其它类型呢?是不是要挨个写判断函数。

go 1.18+ 有个 comparable 类型,定义的可比较类型:

  • Boolean values
  • Integer values
  • Floating point values
  • Complex values
  • String values
  • Pointer values
  • Channel values
  • Interface values
  • Struct values are comparable if all their fields are comparable
  • Array values are comparable if values of the array element type are comparable
  • A value x of non-interface type X and a value t of interface type T are comparable when values of type X are comparable and X implements T

就可以写成如下通用函数:

func ContainsGeneric[T comparable](slice []T, element T) bool {
	for _, e := range slice {
		if e == element {
			return true
		}
	}

	return false
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

使用也很简单

var stringSlice = []string{"item 1", "item 2"}
var intSlice = []int{1, 2, 3}

fmt.Println(Contains(stringSlice, "item 2")) // true
fmt.Println(Contains(intSlice, 4)) // false
  • 1
  • 2
  • 3
  • 4
  • 5

转换成 map 判断

把 slice 元素的值作为 map 的 key,如:

sliceLen := 100
mapInt   := map[int]struct{}{}
for i := 0; i < sliceLen; i++ {
	mapInt[i] = struct{}{}
}
  • 1
  • 2
  • 3
  • 4
  • 5

判断是否存在,为了与上面函数风格相同就这么写

func ContainsMapStr(mp map[string]struct{}, element string) bool {
	_, ok := mp[element]
	return ok
}
  • 1
  • 2
  • 3
  • 4

性能比较

测试 30 个元素结果

sliceLen: 30
goos: darwin
goarch: amd64
cpu: Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
BenchmarkContainsGenericStr
BenchmarkContainsGenericStr-8   	  872523	      1346 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsGenericInt
BenchmarkContainsGenericInt-8   	 5177288	       227.3 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsStr
BenchmarkContainsStr-8          	  862272	      1353 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsInt
BenchmarkContainsInt-8          	 4781001	       256.3 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsMapStr
BenchmarkContainsMapStr-8       	 1623274	       741.8 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsMapInt
BenchmarkContainsMapInt-8       	 1863303	       626.6 ns/op	       0 B/op	       0 allocs/op
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

测试 100 个元素结果

sliceLen: 100
goos: darwin
goarch: amd64
cpu: Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
BenchmarkContainsGenericStr
BenchmarkContainsGenericStr-8   	   66457	     18719 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsGenericInt
BenchmarkContainsGenericInt-8   	  533656	      2182 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsStr
BenchmarkContainsStr-8          	   66378	     17976 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsInt
BenchmarkContainsInt-8          	  560392	      2133 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsMapStr
BenchmarkContainsMapStr-8       	  454953	      2694 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsMapInt
BenchmarkContainsMapInt-8       	  607315	      1956 ns/op	       0 B/op	       0 allocs/op
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

性能小结

  • 使用遍历 slice 判断的方式,slice 元素是 comparable 或具体的 stringint,性能差不多;int 类型比 string 类型要快 6 倍左右。
  • 使用 map 查询时,key 的类型 intstring 稍快一点,相差不大。
  • slicemap 性能跟元素个数有关系,可以参见以前的一个测试 Golang slice 和 map 的查询性能比较24

优化方案,首先看元素个数,其次看元素类型(这里指常见的 int/string)。

  • 15 个以下,无论是 int 还是 string,建议用 slice
  • 15 ~ 100 个,尽量转为 int ,如果不能转为 int 就用 map
  • 100 个以上,果断用 map,int 和 string 都差不多
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/42907
推荐阅读
相关标签
  

闽ICP备14008679号