C++ 高效地写入文件
有没有比在下面的代码位中使用fprintf更有效的写入文件的方法。我正在为数千个文件编写这段代码,而瓶颈是对文件的写入。该文件不一定必须是可读的人。我试着用sprintf语句替换我的fprintf语句,然后在最后执行一个fprintf来将字符串写入文件C++ 高效地写入文件,c++,optimization,io,C++,Optimization,Io,有没有比在下面的代码位中使用fprintf更有效的写入文件的方法。我正在为数千个文件编写这段代码,而瓶颈是对文件的写入。该文件不一定必须是可读的人。我试着用sprintf语句替换我的fprintf语句,然后在最后执行一个fprintf来将字符串写入文件 string tmp_; stringstream mom; mom << path <<"/m" << j << ".mom"; tmp_ = mom.str(); FILE * mom_file
string tmp_;
stringstream mom;
mom << path <<"/m" << j << ".mom";
tmp_ = mom.str();
FILE * mom_file;
mom_file = fopen(tmp_.c_str(),"w");
if (!mom_file)
{
printf("Cannot open file '%s'\n", tmp_.c_str());
exit(1);
}
int params_before=0; //the number of parameters in the vector before this atom due to other atoms
//we use this to keep track of where we are in the interpolation params vector
for(int k=0; k<Natoms; k++)
{
string symbol = Monomers[j].GetAtom(k).GetSymbol();
/*---------------------------MOMENTS--Rotation--and--Printing-----------------*/
//perform rotations of the moments
//Charge is invariant to rotation
if(k==0)
{
fprintf(mom_file, "! monomer properties from interpolation :)\n");
fprintf(mom_file, "! Basis %s\n",basis.c_str());
}
fprintf(mom_file, "\n%s%d %4.10f %4.10f %4.10f Rank %d\n",symbol.c_str(),k+1,Monomers[j].GetAtom(k).GetLocalPosition(0),Monomers[j].GetAtom(k).GetLocalPosition(1),Monomers[j].GetAtom(k).GetLocalPosition(2),moments_rank[k]);
fprintf(mom_file, "%15.12f\n", interpolation_params.Element(params_before));//print charge
params_before += 1;//for charge
if(moments_rank[k] >= 1) //Dipole
{
int tmp = params_before;
interpolation_params.SetBlock(l_1_Wigner.MatrixTimesVector(interpolation_params.GetBlock(3,params_before)),params_before);
params_before +=3;//add 3 to our location after we have rotated the dipole
fprintf(mom_file, "%15.12f %15.12f %15.12f\n", interpolation_params.Element(tmp), interpolation_params.Element(tmp+1), interpolation_params.Element(tmp+2));//print the dipole
}
if(moments_rank[k] >= 2) //Quadrupole
{
int tmp = params_before;
interpolation_params.SetBlock(l_2_Wigner.MatrixTimesVector(interpolation_params.GetBlock(5,params_before)),params_before);
params_before +=5;//add 5 to our location after we have rotated the quadrupole
fprintf(mom_file, "%15.12f %15.12f %15.12f %15.12f %15.12f\n", interpolation_params.Element(tmp), interpolation_params.Element(tmp+1), interpolation_params.Element(tmp+2), interpolation_params.Element(tmp+3), interpolation_params.Element(tmp+4));//print the Quadrupole
}
if(moments_rank[k] >= 3) //Octupole
{
int tmp = params_before;
interpolation_params.SetBlock(l_3_Wigner.MatrixTimesVector(interpolation_params.GetBlock(7,params_before)),params_before);
params_before +=7;//add 7 to our location after we have rotated the Octupole
fprintf(mom_file, "%15.12f %15.12f %15.12f %15.12f %15.12f\n", interpolation_params.Element(tmp), interpolation_params.Element(tmp+1), interpolation_params.Element(tmp+2), interpolation_params.Element(tmp+3), interpolation_params.Element(tmp+4));
fprintf(mom_file, "%15.12f %15.12f\n", interpolation_params.Element(tmp+5), interpolation_params.Element(tmp+6));//print the Octupole
}
if(moments_rank[k] == 4) //Hexadecapole
{
int tmp = params_before;
interpolation_params.SetBlock(l_4_Wigner.MatrixTimesVector(interpolation_params.GetBlock(9,params_before)),params_before);
params_before +=9;//add 9 to our location after we have rotated the Hexadecapole
fprintf(mom_file, "%15.12f %15.12f %15.12f %15.12f %15.12f\n", interpolation_params.Element(tmp), interpolation_params.Element(tmp+1), interpolation_params.Element(tmp+2), interpolation_params.Element(tmp+3), interpolation_params.Element(tmp+4));
fprintf(mom_file, "%15.12f %15.12f %15.12f %15.12f\n", interpolation_params.Element(tmp+5), interpolation_params.Element(tmp+6), interpolation_params.Element(tmp+7), interpolation_params.Element(tmp+8));//print the Hexadecapole
}
if(moments_rank[k] > 4 )
{
printf("oops monomer %d has moments of rank %d and the code can only handle rank 4\n",j,moments_rank[k]);
exit(1);
}
}
fclose(mom_file);
string tmp\ux;
妈妈;
妈妈你说:
该文件不一定必须是可读的人
在这种情况下,请使用二进制格式。使用fwrite
写入数据,使用fread
读取数据
根据我的经验,您从以下几个因素中获得绩效:
不需要进行格式转换
文件的大小较小。需要传输到磁盘并保存在磁盘上的字节数更少
注意事项(谢谢@JerryCoffin):
当您这样做时,数据的可移植性就会降低——例如,写在小端机器上的数据需要转换才能在大端机器上读取。只要您只是在同一台计算机上保存和恢复数据,这就很少会成为问题。片刻[4]<4,那么您将在不关闭文件的情况下退出。除此之外,即使您是fstream并且使用write方法而不是operator,也有三种可能性-您需要进行一些实际测量,以确定哪种方法适用:
1) I/O几乎占用了所有的时间,在这种情况下,您无法从更大的缓冲区()中获得任何改进;我们可以看到你没有在任何不必要的地方冲水;如果文件足够小,效率不高(例如几十KB),并且仍然适合以后使用,那么可以考虑更严格的文件格式和/或压缩和/或更快的驱动器/RAID和/或写入更少的较大文件
2) 代码几乎占用了所有的时间,在这种情况下,您可以尝试跨线程分发代码和/或使用二进制格式来减少转换
3) 它们都很重要,在这种情况下,请尝试上述任何组合瓶颈是写入文件
您是如何分析的?这部分代码是格式化和写入部分,是更大功能的一部分。如果写部分被注释掉,函数运行的时间会大大减少。你怎么知道是代码负责,而不是实际的IO本身?很好的调用(但也可能值得注意的是,当您这样做时,数据的可移植性会降低——例如,在小端机器上写入的数据需要转换才能在大端机器上读取(但只要您只是在同一台机器上保存和恢复数据,这很少会成为问题)。