std :: ofstream.write()在编写字符数组时比单个字符更快吗?

时间:2013-06-26 15:52:24

标签: c++ performance file-io

我想知道代码A是否可能比大多数或大量硬件/系统上的代码B更快。

代码A:

for(i = 0; i < 4; i ++)
    file.write(array[i], 1);

代码B:

// for(i = 0; i < 1; i ++)
    file.write(array[i], 4);

我问的原因是因为我希望能够将一个非常长的64位顺序整数文件写入磁盘。

目前我面临的问题是我的数组(实际上是一个缓冲区)包含8个字节长的对象,而不是1个字节的对象,我可以使用类似的东西轻松编写:

file.write((char*)(array), size_of_array);

我想到了一些解决方案,但它们看起来都很缺乏想象力并向我提出。

第一个是迭代超过8个字节:

for(j = 0; j < size_of_array; j ++)
    for(i = 0; i < 8; i ++) // 8 == sizeof(uint64_t)
        file.write((char*)(array + i + j), 1);

然后我想,为什么不只是写write()为我写8个字节?我被允许这样做吗?

for(j = 0; j < size_of_array; j ++)
    file.write((char*)(array + j), 8);

然后我想,嗯......更进一步:

file.write((char*)(array), 8 * size_of_array);

所以我的问题是,将大量数据写入磁盘的最快方法是什么?

总的来说,我建议编写一个包含400万个对象的缓冲区,并重新填充缓冲区并重新写入,也许是为了创建一个几十GB的文件。

对于那些感兴趣的人来说,这是一个并行处理实验。第1步是生成数据。这就是我现在所处的位置。第1步......

1 个答案:

答案 0 :(得分:0)

我不知道你是否知道这一点,但是你应该知道一些关于以这种方式传输对象的事情:

  1. 这只应针对POD类型进行。

    Plain Old Data类型是没有构造函数的类型。原因是存在可能建立资源的逻辑。如果没有分配资源,则可以使用统一初始化来初始化POD。

  2. POD类型不应包含引用或指针。

    这是因为如果你写一个指向磁盘然后再读回来的指针,它实际上会指向你预期的正确的东西吗?在某些情况下,这个可能是真的,但在大多数情况下它不是。

  3. 您应该使用sizeof()运算符,而不是直接将大小指定为常量。

    类/结构可以在对象中具有填充,用于更改对象的大小以提高访问性能。

  4. 生成的二进制文件特定于字节序。

    如果没有其他系统的转换,读取以这种方式生成的文件将无法以相同的方式读取。

  5. 生成的二进制文件是特定于编译器的。

    同样,这与填充有关。不同的编译器可能会在不同的位置放置填充。

  6. 如果将这些考虑在内,是的,您可以按照自己的意思行事,并且在减少函数调用次数时应该稍快一些。