我想处理的文本文件大小超过>主要包含DNA序列的50 GB。我想按块处理这个文件块,如下所述 -
我有以下问题:
1. How to read a file chunk by chunk efficiently?
2. Alternative approach that i should follow.
3. Any algo/framework that i should go for.
由于
答案 0 :(得分:0)
假设您在读取数据时没有对数据进行大量计算,那么您的程序几乎肯定会受到I / O限制 - 也就是说,CPU和RAM的运行速度会快得多而不是硬盘驱动器的带宽,操作的总速度几乎完全取决于硬盘的数据读取速度。
因此,我建议做的第一件事就是计算读取整个文件需要多长时间(而不是对所产生的内存数据做任何事情)。这将为您提供“最佳情况” - 即如果您的非I / O代码如此高效以至于不花时间,您可以期待什么样的性能。然后,您的目标是尝试让您的实际程序尽可能接近该性能。
至于如何从磁盘读取数据,它可能无关紧要,因为像fread()和fgets()这样的调用在C标准库和文件系统层都使用缓冲,所以即使你正在少量读取(例如,一次一行文本),当请求到达实际I / O硬件时,它是一个更大(更有效)的预读请求,无论如何都将有效地使用硬件。也就是说,你可以尝试在单个fread()调用中以兆字节(或100兆字节)读取(如果你想要(然后通过巨型缓冲区来解析各行文本),但我认为你会发现它不会明显快于在循环中调用fgets()直到你到达文件的末尾。
(并且对于不可避免的C ++纯粹主义者抱怨说因为这个问题被标记为C ++,OP应该使用iostreams ...确定,这也值得尝试,尽管我发现iostream难以使用和一些实现众所周知,iostream是低效的。幸运的是,像这样的问题很简单,测试多种方法并测量哪种方法提供最佳性能是切实可行的。
就替代方法而言 - 如果你想要比上面提到的更快的加速,你将要开始考虑改变问题的参数。由于您(可能)I / O受限,因此加快速度的最佳方法是读取较少的数据。您的文件格式是否真的需要是未压缩的ASCII文本?是否可以将其更改为更紧凑的二进制格式(例如,如果我记得我的遗传学正确的话,每个碱基对2位),那么文件大小可能是12GB而不是50GB?和/或它是否可以存储zlib压缩,进一步减小文件大小?由于CPU现在与磁盘相比如此之快,因此读取较小的文件然后对其进行zlib膨胀可能比读取更大的文件并逐字使用(!)
更快答案 1 :(得分:0)
此主题似乎与阅读文件有关 multithread read from disk?
看来,由于您只是在阅读,最好的方法是按顺序读取,直到最后,每次有一个X字节的本地缓冲区时,就会产生一个计算线程。
这当然只有在每个块计算是独立的时才可行。
答案 2 :(得分:0)
如果磁盘容量不是问题,我建议使用split
命令(或类似命令)对文件进行分块。
例如,使用-l
命令的split
选项生成~100MB的文件。如果文件采用多行FASTA格式,请确保FASTA标头和序列均在一行中,然后为-l
的值指定偶数。
然后编写一个处理单个块的程序。根据需要并行化此工作流程(批处理调度程序等)以处理所有块。