golang对slice的一些优化的操作

对slice高效的过滤

利用slice的特性,我们在过滤并删除slice的数据不必要在重新make一个新的slice因为这样会重新创建数组浪费空间。所以最好借用原来的slice在原来的slice基础上创建slice,这样在删除时底层不会重新创建数组。

func Filter(s []byte, fn func(x byte) bool) []byte {
	b:=s[:0] //我们利用传过来的slice重新创建一个slice,底层不会重新创建数组
	for _, x := range s {
		if !fn(x) {
			b = append(b, x)
		}
	}
	return b
}

slice逃逸

demo1

例如, getData函数加载整个文件到内存,返回从index开始以后的数据。

func getData(path string,index int)[]byte{
	if
	b, err := ioutil.ReadFile(filename)//加载整个文件
	if err!=nil{
		fmt.Println(err.Error())
		return nil
	}
	return b[index:]  // 返回从index开始的数据
}

该代码查找到对应的数据后直接返回原slice,由于存放原数据的slice被别的函数引用,那么该slice会被放到堆内存中而不是随着函数结束而被释放的栈内存。这样时间长就会对整个系统性能产生影响。
要修复这个问题,可以将需要的数据的数据复制到一个新的切片中返回即可,这样会节省堆内存[0:index]这么多的空间。

func getData(path string,index int)[]byte{
	if
	b, err := ioutil.ReadFile(filename)//加载整个文件
	if err!=nil{
		fmt.Println(err.Error())
		return nil
	}
	return appen([]byte{},b[index:]...)  // 返回从index开始的数据
}

demo2

如果slice里面保存的是指针类型的数据,要删除slice里面的数据,如果slice底层数组还在被引用,那么被删除的元素空间是不会被释放的

// 删除最后一个元素
func del(arr []*int)[]*int{
	arr = arr[:len(arr)-1] // 删除最后一个元素
	return arr
}

这样做最后一个元素对应的值得内存空间不会被释放,因为底层数组根本没动依旧保存着最后一个值对应的地址。

正确做法:

// 删除最后一个元素
func del(arr []*int)[]*int{
	arr[len(arr)-1]=nil // 取消底层数组和最后一个元素的联系,使得gc回收
	arr = arr[:len(arr)-1] // 删除最后一个元素
	return arr
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值