2017-02-18 79 views
-3

在C++中写入和读取混合数据类型(即无符号整数,double,uint64_t,字符串)的有效方法。高效地在C++中读写混合数据类型 - 11

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

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++

+2

如果你开始分析20个字节的数据,你应该从基础知识开始,就如何有效地完成这项任务进行一些研究。你有可能帮助你的同事吗? –

+0

@LightnessRacesinOrbit不幸的是没有 –

+1

然后,请原谅我这么说,看起来你和你的团队不适合这项任务。你是如何背负它的? –

回答

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++ iostream调用,而该实现使用C fopen()/fread()/fwrite()/fclose() API调用。一些C++ iostream实现是known to be somewhat inefficient,但(简单的)C I/O API不太可能无效。如果没有别的,比较C++和C版本的性能会让你确认或否认你的C++库的iostream实现是一个瓶颈。

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

如果一切都失败了,最后要做的就是减少需要读取或写入的数据量。是否有部分数据可以单独存储,以便您不需要每次都读取和写入它们?有没有数据可以更紧凑地存储(例如,数据中常用的字符串可以存储为整数代码而不是字符串)?如果您在写入数据之前使用zlib压缩数据,以便写入的数据更少?您看起来在您的示例中编写的数据看起来可能适合压缩,可能会将您的20GB文件减少到5GB文件左右。等等