Memory 重用io.Reader和捕获长度
我正在使用一个远程API,它返回一个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 :=
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带来更多的工作-这是没有办法的。我将使用不同的初始缓冲区大小和最大缓冲区大小进行一些测试,并查看实际测试数据的最佳性能。