有效地保留最后N个推送项目的集合

时间:2019-04-09 17:28:59

标签: arrays go memory slice

给出:

  1. 具有已知容量的切片
  2. 容量和分片数量很大,将使用大约15MB的内存,因此我不想浪费内存并希望保持最小的内存。
  3. 切片将通过删除第一个元素并将新元素添加到切片末尾来进行更新。

b = append(b[1:], n)将增加容量

我写了

转移和分配自己

func shiftAndPut(a []int, n int) (b []int) {
    b = make([]int, cap(a), cap(a))
    for i,v := range(a[1:]) {
        b[i] = v
    }
    b[len(b)-1] = n
    return
}

https://play.golang.org/p/7xIBh0UPp2w

它保持容量不变,但需要进行各种计算

  1. 一次迭代切片,
  2. 调用函数,
  3. 短时间内的新变量
  4. 范围函数中的子切片,可增加更多计算,

还有其他更优化的方法吗?

1 个答案:

答案 0 :(得分:1)

切片环形缓冲区,自定义实现:

data := make([]int, cap, cap)
pointer := 0

data[pointer] = newData
pointer = (pointer+1) % cap

custom/ring软件包实现:

data := ring.New(cap)
data.Value = newData
data = data.Next()

在评论主题中提出建议后,我在benchmarkslice custom shifting之间做了custom/ring

BenchmarkCustom1000-4         100000         17322 ns/op
BenchmarkRing1000-4           100000         22824 ns/op
BenchmarkCustom-4           100000000           17.4 ns/op
BenchmarkRing-4             100000000           22.8 ns/op

使用变量(指针或标志)的自定义切片移位更快,并且内存得到了优化。