同时从文件中读取字节

时间:2018-04-17 00:50:32

标签: go

我在Go中编写了一个程序,它从文件中读取单个字节并检查是否设置了哪些位。这些文件通常很大(大约10 - 100 GB),所以我不想将整个文件读入内存。该程序通常必须检查数百万个单独的字节。

现在,我执行这些读取的方式是使用os.File.ReadAt()。这最终变得很慢,所以我尝试使用Goroutines加速它。例如:

var wg sync.WaitGroup
threadCount := 8

for i := 0; i < threadCount; i += 1 {
    wg.Add(1)
    go func(id int) {
        defer wg.Done()
        index := id
        myByte := make([]byte, 1)

        for index < numBytesInFile-1 {  // Stop when thread would attempt to read byte outside of file
            fmt.Println(file.ReadAt(myByte, index))
            index += threadCount
        }
    }(i)
}
wg.Wait()

然而,在这里使用Goroutines根本没有加快程序的速度(事实上,它因为开销而略微变慢)。我原以为光盘上的文件可以同时读取,只要它们以只读模式打开(我在程序中这样做)。我要求的是不可能的,或者是否有某种方式我在Go中对文件进行并发读取?

1 个答案:

答案 0 :(得分:2)

你的速度慢是因为I / O而不是CPU。添加更多线程不会加速您的程序。阅读有关Amdahl法律的内容。 https://en.wikipedia.org/wiki/Amdahl%27s_law

如果您不想将完整文件读入内存,可以使用缓冲读取器并读入部分https://golang.org/pkg/bufio/#NewReader,或者您甚至可以考虑使用实验性内存映射文件包:{{3 }}

要了解有关内存映射文件的更多信息,请参阅https://godoc.org/golang.org/x/exp/mmap