如何有效地写入大量文件

时间:2018-01-30 05:51:03

标签: c++ io gzip zlib

我正在尝试编写一个程序,根据每个序列的某个段内的值将大量基因序列分成许多文件。例如,序列可能看起来像

AGCATGAGAG...
GATCAGGTAA...
GATGCGATAG...
... 100 million more

然后,目标是根据位置2到7(6个碱基)的序列将读取分成单个文件。所以我们得到像

这样的东西
AAAAAA.txt.gz
AAAAAC.txt.gz
AAAAAG.txt.gz
...4000 more

现在天真地我实现了一个

的C ++程序
  • 读入每个序列
  • 打开相关文件
  • 按顺序写入
  • 关闭文件

这样的东西
#include <zlib.h>

void main() {
    SeqFile seq_file("input.txt.gz");
    string read;

    while (read = seq_file.get_read) {
        string tag = read.substr(1, 6);
        output_path = tag + "txt.gx";

        gzFile output = gzopen(output_path.c_str(), "wa");
        gzprintf(output, "%s", read);
        gzclose(output);
    }
}

与将整个内容写入单个其他文件相比,这是无法忍受的缓慢。

这种情况有什么瓶颈?如果由于系统限制而无法同时打开所有文件,我将如何提高性能?

4 个答案:

答案 0 :(得分:1)

由于打开文件很慢,您需要减少打开的文件数。实现此目的的一种方法是对输入进行多次传递。打开输出文件的子集,对输入进行传递,只将数据写入这些文件。完成后,关闭所有这些文件,重置输入,打开一个新子集,然后重复。

答案 1 :(得分:1)

瓶颈是打开和关闭输出文件。如果你可以以某种方式将其移出循环,例如通过同时打开多个输出文件,您的程序应该显着加快。在最好的情况下,可以同时打开所有4096个文件,但如果你遇到一些系统障碍,即使打开较少数量的文件,并且通过文件进行多次传递也应该更快打开和关闭文件紧紧的循环。

答案 2 :(得分:0)

压缩可能会减慢写入速度,写入文本文件然后压缩可能值得一试。

打开文件是一个瓶颈。有些数据可以存储在容器中,当达到一定大小时,将最大的数据集写入相应的文件中。

答案 3 :(得分:0)

我实际上无法回答这个问题 - 因为要做到这一点,我需要访问您的系统(或合理精确的副本)。磁盘的类型及其连接方式,内存的数量和类型以及CPU的型号/数量都很重要。

然而,有一些不同的事情需要考虑,这可能会有所帮助(或者至少告诉你“你不能做得比这更好”)。

首先找出占用时间的内容:CPU或磁盘I / O?

使用topsystem monitor或其他类似内容来衡量应用程序使用的CPU使用情况。

编写一个简单的程序,将单个值(零?)写入文件,而不是压缩文件,其大小与文件中的大小相似。将其与编写gzip文件所需的时间进行比较。如果时间大致相同,那么你就受I / O限制了,你所做的事情可能并不重要。

如果你有大量的CPU使用率,你可能想要将写作工作分成多个线程 - 你显然不能真正用读取来做,因为它必须是顺序的(在多个线程中读取gzip不是如果可能的话,很容易,所以我们不要试试。每个CPU核心使用一个线程,因此如果你有4个核心,则使用1来读取,使用3来写入。你可能没有达到4倍的表现,但你应该得到很好的改善。

当然,在某些时候,你将受到磁盘速度的限制。然后唯一的选择是购买更好的磁盘(如果你还没有!)