I'm currently writing out billions of binary records to ASCII files (ugh). I've got things working just fine, but I'd like to optimize the performance if I can. The problem is, the user is allowed to select any number of fields to output, so I can't know at compile-time which of 3-12 fields they'll include.
Is there a faster way to construct lines of ASCII text? As you can see, the types of the fields vary quite a bit and I can't think of a way around the series of if() statements. The output ASCII file has one line per record, so I've tried using a template QString constructed with arg, but that just slowed things down about 15%.
A faster solution doesn't have to use QTextStream, or necessarily write directly to the file, but the output is too large to write the whole thing to memory.
Here's some sample code:
QFile outfile(outpath);
if(!outfile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
{
qWarning("Could not open ASCII for writing!");
return false;
} else
{
/* compute XYZ precision */
int prec[3] = {0, 0, 0}; //these non-zero values are determined programmatically
/* set up the writer */
QTextStream out(&outfile);
out.setRealNumberNotation(QTextStream::FixedNotation);
out.setRealNumberPrecision(3);
QString del(config.delimiter); //the user chooses the delimiter character (comma, tab, etc) - using QChar is slower since it has to be promoted to QString anyway
/* write the header line */
out << "X" << del << "Y" << del << "Z";
if(config.fields & INTFIELD)
out << del << "IntegerField";
if(config.fields & DBLFIELD)
out << del << "DoubleField";
if(config.fields & INTFIELD2)
out << del << "IntegerField2";
if(config.fields & TRIPLEFIELD)
out << del << "Tri1" << del << "Tri2" << del << "Tri3";
out << "\n";
/* write out the points */
for(quint64 ptnum = 0; ptnum < numpoints; ++ptnum)
{
pt = points.at(ptnum);
out.setRealNumberPrecision(prec[0]);
out << pt->getXYZ(0);
out.setRealNumberPrecision(prec[1]);
out << del << pt->getXYZ(1);
out.setRealNumberPrecision(prec[2]);
out << del << pt->getXYZ(2);
out.setRealNumberPrecision(3);
if(config.fields & INTFIELD)
out << del << pt->getIntValue();
if(config.fields & DBLFIELD)
out << del << pt->getDoubleValue();
if(config.fields & INTFIELD2)
out << del << pt->getIntValue2();
if(config.fields & TRIPLEFIELD)
{
out << del << pt->getTriple(0);
out << del << pt->getTriple(1);
out << del << pt->getTriple(2);
}
out << "\n";
} //end for every point
outfile.close();