我有10个大的(3400万个单元格)2D网格向量存储双精度数。写入时,它们的尺寸超过200 mb。我使用ofstream对象将它们写入文本文件(csv格式),一次一个元素,使用两个for循环(一个用于我的行,一个用于我的列)。他们采取长期写作的方式。是否有更快的方式从这些向量写入?
这是我的代码:
// Resizing of vectors
flowDirGrid.resize(rows, std::vector<double>(cols, NODATA));
// Do some processing
....
// Outputting processed data
ofstream outfile3("FlowDir.dat");
if(!outfile3.good())
return;
for(int i=0; i<rows; i++)
{
for (int j=0; j<cols; j++)
{
if(elevation[i][j]!=NODATA)
outfile3 << flowDirGrid[i][j]<<" ";
else
outfile3 << NODATA<<" ";
}
outfile3 << std::endl;
}
outfile3.close();
我正在使用C ++和Visual Studio 2012.
修改即可。我删除了所有std :: endl实例并替换为“\ n”,并且仍需要17分钟来编写每个输出文件。我可能会转向使用推荐的C方法。
使用三元而不是if-else梯子会加速吗?
答案 0 :(得分:2)
C ++ iostream库很方便,但速度很慢。 fprintf
会更好地为您服务。另外,使用&#39; \ n&#39;而不是endl
,因为后者强制流冲洗。
#include <cstdio>
#include <chrono>
#include <fstream>
#include <iostream>
#include <random>
#include <vector>
using namespace std;
using namespace std::chrono;
void PrintC(const double * data, size_t n, const char * path)
{
FILE * f = fopen(path, "w");
for (size_t i(0); i != n; ++i)
fprintf(f, "%lf ", data[i]);
fclose(f);
}
void PrintCpp(const double * data, size_t n, const char * path)
{
ofstream f(path);
for (size_t i(0); i != n; ++i)
f << data[i] << ' ';
}
template<typename PrintT>
void Time(const vector<double> & data, PrintT Print, const char * path, const char * text)
{
auto s = steady_clock::now();
Print(data.data(), data.size(), path);
auto f = steady_clock::now();
cout << text << ": " << duration_cast<duration<double>>(f - s).count() << endl;
}
int main()
{
vector<double> data(34000000);
default_random_engine generator;
uniform_real_distribution<double> distribution(0.0, 1.0);
for (size_t i(0); i != data.size(); ++i)
data[i] = distribution(generator);
Time(data, PrintC, "test1.dat", "c");
Time(data, PrintCpp, "test2.dat", "c++");
}
Visual Studio 2013 Professional,发布配置:
c:17.2682
c ++:32.0839
答案 1 :(得分:1)
200 MB的20分钟似乎真的长。您遇到性能问题,因此必须按顺序测试元素。
取一个200 mb并复制它(直接在os级别)。如果需要大约10分钟,瓶颈在这里:购买更快的磁盘
制作一个测试程序,生成随机值集(不是全部为0.因为0.转换比其他双值更简单,所以只是*不同的值),写下时间(至少包括第二个)使用上面的代码来编写文件并再次写入时间 - 或者,您可以使用当前代码只添加两次。运行几次。如果它比第一次测试花费的时间要长得多,请在此报告第一次测试和第二次测试的时间。
如果上述测试均未花费大约10分钟,则问题出现在其余代码中......
答案 2 :(得分:0)
根据this answer std::endl
导致刷新流。请尝试使用\n
。