在我自己推出之前,是否有io.Pipe的缓存版本(在标准库或第三方库中)?
上下文:我尝试使用this solution解析用bzip2压缩的JSON数据,以便解压缩和解析并行发生,但发现加速非常小。解析未压缩数据每百万条记录大约需要22秒。解压缩那么多数据需要大约相同的时间。正如预期的那样,在单个线程上执行它们需要大约44秒。使用上述解决方案需要约41秒。
io.Pipe的文档说:
管道上的读取和写入是一对一匹配,除非 消耗单个Write需要多次读取。也就是说,每一个 写入PipeWriter块,直到它满足一个或多个 从完全使用写入数据的PipeReader读取。该 数据直接从Write复制到相应的Read(或 读取);没有内部缓冲。
我怀疑这可能是一个问题,这取决于bzip2解压缩程序写入数据的方式以及JSON解析器读取数据的方式,因此我想尝试缓冲版本。
答案 0 :(得分:4)
这是bufio
包的用途。它允许您将任何io.Reader
转换为使用NewReader
或任何io.Writer
的缓冲读者,并将其转换为NewWriter
的缓冲作者。
(缓冲IO是否真的会帮助解决您的具体问题,我不知道......)
答案 1 :(得分:1)
您可以使用https://github.com/djherbis/nio中的缓冲管道,如下所示:
import (
"github.com/djherbis/buffer"
"github.com/djherbis/nio"
)
...
b := buffer.New(32*1024)
pr, pw := nio.Pipe(b)
...
答案 2 :(得分:0)
如果要进行异步操作,即在单独的goroutine上进行读取,则还可以使用几年前使用的readahead
:
https://github.com/klauspost/readahead
示例:
ra := readahead.NewReader(input)
defer r.Close()
pr, pw := nio.Pipe(ra)
使用默认设置时,它将在管道准备就绪时最多读取四个将发送的1MB缓冲区。
答案 3 :(得分:0)
我的https://github.com/acomagu/bufpipe界面简单并且运行良好。
r, w := bufpipe.New(nil)
io.WriteString(w, "abc") // No blocking.
io.WriteString(w, "def") // No blocking, too.
w.Close()
io.Copy(os.Stdout, r)
// Output: abcdef