我有一个软件可以执行一组实验(C ++)。 没有存储结果,所有实验都需要一分多钟。 生成的数据总量等于2.5 GB,这个数据太大,无法存储在内存中直到实验结束,然后写入文件。 因此我把它们写成块。
for(int i = 0; i < chunkSize;i++){
outfile << results_experiments[i] << endl;
}
,其中 ofstream outfile(“data”); 和outfile只在最后关闭。
然而,当我用4700千字节(实际上是4700 / Chunksize = results_experiments元素的大小)编写它们时,实验需要大约50倍(超过一小时......)。这是不可接受的,并使我之前的优化尝试看起来相当愚蠢。特别是因为这些实验再次需要使用许多不同的参数设置等(至少100次,但最好是更多)
具体我的问题是:
写什么理想的chunksize?
目前我写数据的方式是否比(或效率非常低)更有效?
基本上:帮助我尽可能小地引入文件IO开销..
我认为应该可以更快地执行此操作,因为复制(写入和读取!)生成的文件(相同大小),花了我一分钟......
代码应该是相当独立于平台的,不使用任何(非标准)库(我可以为单独的平台提供单独的版本以及更复杂的安装说明,但这很麻烦..) 如果不可能在5分钟内获得总实验时间,没有平台/库依赖(并且可能),我将认真考虑引入这些。 (平台是windows,但至少应该是一个简单的linux端口)
感谢您的努力。
答案 0 :(得分:5)
对于初学者而言,不为每个块冲洗缓冲区似乎是个好主意。似乎也可以异步执行IO,因为它完全独立于计算。您还可以使用mmap
来提高文件I / O的性能。
答案 1 :(得分:3)
如果输出不必是人类可读的,那么您可以研究二进制格式。以二进制格式存储数据比文本格式占用更少的空间,因此需要更少的磁盘i / o。但如果数据都是字符串,那么差别不大。因此,如果您尽可能多地写出数字而不是格式化文本,那么您将获得巨大收益。
但是我不确定是否/如何使用STL iostream。 C风格的方式是使用fopen(..., "wb")
和fwrite(&object, ...)
。
我认为boost::Serialisation可以使用<<
运算符进行二进制输出。
另外,你可以减少你写的金额吗?例如没有格式化或冗余文本,只是最低限度。
答案 2 :(得分:0)
在写入ofstream时,endl是否刷新缓冲区是依赖于实现的 -
您也可以尝试增加ofstream的缓冲区大小
char *biggerbuffer = new char[512000];
outfile.rdbuf()->pubsetbuf(biggerbuffer,512000);
pubsetbuf的可用性可能因您的iostream实现而异[/ p>