go 切片内存技巧

切片内存技巧

在本节开头的数组部分我们提到过有类似[0]int的空数组,空数组一般很少用到。但是对于切片来说,len0但是cap容量不为0的切片则是非常有用的特性。当然,如果lencap都为0的话,则变成一个真正的空切片,虽然它并不是一个nil值的切片。在判断一个切片是否为空时,一般通过len获取切片的长度来判断,一般很少将切片和nil值做直接的比较。

比如下面的TrimSpace函数用于删除[]byte中的空格。函数实现利用了0长切片的特性,实现高效而且简洁。

func TrimSpace(s []byte) []byte {
    b := s[:0]
    for _, x := range s {
        if x != ' ' {
            b = append(b, x)
        }
    }
    return b
}

其实类似的根据过滤条件原地删除切片元素的算法都可以采用类似的方式处理(因为是删除操作不会出现内存不足的情形):

func Filter(s []byte, fn func(x byte) bool) []byte {
    b := s[:0]
    for _, x := range s {
        if !fn(x) {
            b = append(b, x)
        }
    }
    return b
}

切片高效操作的要点是要降低内存分配的次数,尽量保证append操作不会超出cap的容量,降低触发内存分配的次数和每次分配内存大小。



posted @ 2020-12-24 16:49  hubb  阅读(283)  评论(0编辑  收藏  举报