有没有一种有效的方法来回收容量过剩的切片?

我有大量已分配的切片(几百万个)append。我敢肯定,其中很多都超出了产能。我想尝试减少内存使用。

我的第一次尝试是迭代所有这些,分配一个新的切片len(oldSlice)并复制值。不幸的是,这似乎会增加内存使用量(最多翻倍),并且垃圾收集回收内存的速度很慢。

有没有一种很好的通用方法来减少大量容量过剩的切片的内存使用量?


慕仙森
浏览 209回答 2
2回答

月关宝盒

如果不知道确切的问题,就很难选择正确的策略来分配缓冲区。一般来说,您可以尝试重用缓冲区:type buffer struct{}var buffers = make(chan *buffer, 1024)func newBuffer() *buffer {&nbsp; &nbsp; select {&nbsp; &nbsp; case b:= <-buffers:&nbsp; &nbsp; &nbsp; &nbsp; return b&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; return &buffer{}&nbsp; &nbsp; }}func returnBuffer(b *buffer) {&nbsp; &nbsp; select {&nbsp; &nbsp; case buffers <- b:&nbsp; &nbsp; default:&nbsp; &nbsp; }}

慕桂英3389331

中使用的启发式方法append可能不适用于所有应用程序。它专为在您不知道要存储的数据的最终长度时使用而设计。我会尽量减少您分配的额外容量,而不是稍后对其进行迭代。这是一种策略的简单示例,即仅在长度未知时使用缓冲区,并重用该缓冲区:type buffer struct {&nbsp; names []string&nbsp; ... // possibly other things}// assume this is called frequently and has lots and lots of namesfunc (b *buffer) readNames(lines bufio.Scanner) ([]string, error) {&nbsp; // Start from zero, so we can re-use capacity&nbsp; b.names = b.names[:0]&nbsp; for lines.Scan() {&nbsp; &nbsp; b.names = append(b.names, lines.Text())&nbsp; }&nbsp; // Figure out the error&nbsp; err := lines.Err()&nbsp; if err == io.EOF {&nbsp; &nbsp; err = nil&nbsp; }&nbsp; // Allocate a minimal slice&nbsp; out := make([]string, len(b.names))&nbsp; copy(out, b.names)&nbsp; return out, err}当然,如果你需要一些可以安全并发使用的东西,你需要修改它;为此,我建议使用缓冲通道作为存储缓冲区的漏桶。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go