Memory 重用io.Reader和捕获长度

Memory 重用io.Reader和捕获长度,memory,go,garbage-collection,Memory,Go,Garbage Collection,我正在使用一个远程API,它返回一个io.ReadCloser(因此没有读取就无法获得长度),需要在响应中添加一个包含原始io.Reader数据长度的头,然后将结果io.Reader写入io.Writer 除了省略错误处理之外,以下函数在功能上是正确的。但是,addHeaderBytes缓冲函数会产生7个分配,而addHeaderBytes缓冲函数会产生8个: func addHeaderBytesBuffer(in io.Reader) (out io.Reader) { buf :=

我正在使用一个远程API,它返回一个
io.ReadCloser
(因此没有读取就无法获得长度),需要在响应中添加一个包含原始
io.Reader
数据长度的头,然后将结果
io.Reader
写入
io.Writer

除了省略错误处理之外,以下函数在功能上是正确的。但是,
addHeaderBytes缓冲
函数会产生7个分配,而
addHeaderBytes缓冲
函数会产生8个:

func addHeaderBytesBuffer(in io.Reader) (out io.Reader) {
    buf := new(bytes.Buffer)
    io.Copy(buf, in)

    header := createHeader(buf.Len())
    return io.MultiReader(header, buf)
}

func addHeaderTeeReader(in io.Reader) (out io.Reader) {
    buf := new(bytes.Buffer)
    n, _ := io.Copy(ioutil.Discard, io.TeeReader(in, buf))

    return io.MultiReader(createHeader(int(n)), buf)
}

func createHeader(length int) (out io.Reader) {
    return strings.NewReader(fmt.Sprintf("HEADER:%d", length))
}

我正在维护一个
sync.Pool
bytes.Buffer
实例以重复使用以降低GC压力,但是有没有更有效的方法来做到这一点?

尝试创建一个容量大的缓冲区,这样就不需要重新分配。看见另外,完成后不要忘记调用。我为
sync.Pool
创建了包装方法,以确保缓冲区被重置(是的:)不幸的是,所需的缓冲区大小范围很大,因此决定使用任意大的缓冲区(甚至阻止大缓冲区重新进入池)仍然会给GC带来相当大的工作。处理许多分配,或大型分配,会给GC带来更多的工作-这是没有办法的。我将使用不同的初始缓冲区大小和最大缓冲区大小进行一些测试,并查看实际测试数据的最佳性能。