在C ++中有效地读写混合数据类型 - 11

时间:2017-02-18 02:13:15

标签: c++ c++11

在c ++文件中编写和读取混合数据类型(即无符号整数,双精度,uint64_t,字符串)的有效方法。

我需要在磁盘上写入和读取包含混合数据类型的数据。我使用以下方法写入数据。然而它变得非常缓慢。

fstream myFile;
myFile.open("myFile", ios::binary, ios::out);
double x; //with appropriate initialization
myFile<<x;
int y;
myFile<<y;
uint64_t z;
myFile<<z;
string myString;
myFile<<myString;

然而,对于大小为20 GB的大数据,这种方法效率非常低。有人可以建议我如何在c ++中快速读取和编写混合数据类型

1 个答案:

答案 0 :(得分:1)

我认为您需要确定的第一件事是您的程序实际上是否慢。

我的意思是什么?当然你认为它很慢,但它是否因为你的特定程序效率低而速度慢,或者它是否因为将20千兆字节的数据写入磁盘本身就是一项非常耗时的操作而感到缓慢?

所以我要做的第一件事就是在你的硬盘上运行一些基准测试,以确定它的原始速度(以兆字节/秒为单位,或者其他)。有商业应用程序可以执行此操作,或者您可以使用内置实用程序(如Unix或Mac上的dd)来大致了解特定硬盘驱动器读取或写入所需的时间20千兆字节的虚拟数据:

dd if=/dev/zero of=junk.bin bs=1024 count=20971520

dd if=junk.bin of=/dev/zero bs=1024

如果dd(或其他)能够以比程序更快的速度传输数据,那么您的程序就有改进的空间。另一方面,如果dd的速度并不比你的程序速度快得多,那么除了出去购买之外你什么也做不了。更快的硬盘(或者SSD或RAM驱动器或其他东西)。

假设上面的测试确实表明你的程序效率低于它可能的效率,我首先要尝试用一个使用C fopen()/fread()/fwrite()/fclose() API调用的等效实现替换你的C ++ iostream调用。一些C ++ iostream实现是known to be somewhat inefficient,但(更简单的)C I / O API不太可能效率低下。如果没有别的,比较C ++和C版本的性能可以让你确认或否认你的C ++库的iostreams实现是一个瓶颈。

如果即使是C API也无法为您提供所需的速度,我接下来要考虑的是将文件格式更改为更易于阅读或写入的内容;例如,假设您有足够的内存,可能只需使用mmap()将大块虚拟地址空间与文件内容相关联,然后只需读取/写入文件内容,就像它是RAM一样。 (这可能会或可能不会使事情变得更快,具体取决于您访问数据的方式)。

如果所有其他方法都失败了,最后要做的就是减少需要读取或写入的数据量。是否有部分数据可以单独存储,以便您不必每次都进行读写操作?那里有数据你可以更紧凑地存储(例如,你的数据中可能存在常用的字符串,你可以存储为整数代码而不是字符串)?如果在编写数据之前使用zlib压缩数据会怎样,那么要写入的数据更少?您在示例中看起来正在编写的数据看起来可能适合压缩,可能会将您的20GB文件减少到5GB左右的文件。等