Go开源宝藏基于 Golang 语法的性能调优技巧(数组的遍历)
Posted 小生凡一
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go开源宝藏基于 Golang 语法的性能调优技巧(数组的遍历)相关的知识,希望对你有一定的参考价值。
1. 数组的遍历
数组和切片的遍历方式一样,所以我们这里就不进行区分。
我们一般用以下两种方式
- 直接取下标方式
for i:=0;i<len(nums);i++
...
我们先来讲一下这种方式,我们都知道数组在内存中存储是连续的。所以我们直接用下表取出数组中的元素,就是直接在数组的原地址中获取,这种写法比较像c语言的写法。所以这种方式是非常快的。
- range 遍历方式
for index,item := range items
...
我们再来讲一下这种方式,这种方式的情况比第一种要更加美观,和python的 for 循环遍历比较像 ,但是同样的,在遍历items数组的过程中,其实我们得到的item只是一个拷贝的值,也就是会在内存中拷贝一份items中的元素。虽然这种遍历方式比较美观,但是这较于第一种来说是,其性能是有所降低的。
benchmark测试
下面的这一段测试逻辑就是将三种遍历的方式进行 benchmark 测试,事先进行赋值并转化成字符串,然后再进行相同的操作,将字符串进行拼接。
为了测试结果尽可能的快,所以我们的字符串拼接使用了string.builder
这个方法来执行。
/*
100000
BenchmarkByRange
BenchmarkByRange-8 763 1393727 ns/op
BenchmarkByIndex
BenchmarkByIndex-8 1503 1194054 ns/op
BenchmarkByIndexAndLen
BenchmarkByIndexAndLen-8 1818 745112 ns/op
*/
func BenchmarkByRange(b *testing.B)
elems := make([]string, 100000, 100000)
for i := 0; i < 100000; i++
elems[i] = strconv.Itoa(i)
var builder strings.Builder
b.ResetTimer()
for i := 0; i < b.N; i++
for _, elem := range elems
builder.WriteString(elem)
b.StopTimer()
func BenchmarkByIndex(b *testing.B)
elems := make([]string, 100000, 100000)
for i := 0; i < 100000; i++
elems[i] = strconv.Itoa(i)
var builder strings.Builder
b.ResetTimer()
for i := 0; i < b.N; i++
for j := 0; j < len(elems); j++
builder.WriteString(elems[j])
b.StopTimer()
func BenchmarkByIndexAndLen(b *testing.B)
elems := make([]string, 100000, 100000)
for i := 0; i < 100000; i++
elems[i] = strconv.Itoa(i)
length := len(elems)
var builder strings.Builder
b.ResetTimer()
for i := 0; i < b.N; i++
for j := 0; j < length; j++
builder.WriteString(elems[j])
b.StopTimer()
在上面的测试代码中,我们可以看出,第二种是要比第一种性能稍微高了一点。
而第三种和第二种的区别就是将数组长度往外放,也就是说,当我们需要在一段逻辑中不断遍历这个数组,我们可以事先规定好长度,因为len(nums)
也是有性能影响的,所以我们在遍写代码的时候可以稍微注意一下。
以上是关于Go开源宝藏基于 Golang 语法的性能调优技巧(数组的遍历)的主要内容,如果未能解决你的问题,请参考以下文章