Phl*_*ous 5 optimization qt qt4
我目前正在将数十亿条二进制记录写入 ASCII 文件(呃)。我已经一切正常,但如果可以的话,我想优化性能。问题是,用户可以选择任意数量的字段进行输出,因此我无法在编译时知道它们将包含 3-12 个字段中的哪一个。
有没有更快的方法来构造 ASCII 文本行?如您所见,字段的类型差异很大,我想不出解决一系列 if() 语句的方法。输出 ASCII 文件每条记录有一行,因此我尝试使用由arg 构造的模板QString,但这只会使速度减慢约 15%。
更快的解决方案不必使用 QTextStream,也不必直接写入文件,但输出太大而无法将整个内容写入内存。
这是一些示例代码:
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();
Run Code Online (Sandbox Code Playgroud)
(这并没有回答探查器问题。它试图回答最初的问题,即性能问题。)
我建议在这种情况下完全避免使用 QTextStream 看看是否有帮助。它可能有助于提高性能的原因是,涉及到开销,因为文本在内部编码为 UTF-16进行存储,然后在写出时再次解码为 ASCII 或 UTF-8。您有两个不需要的转换。
尝试仅使用标准 C++std::ostringstream类。它与 QTextStream 非常相似,只需在代码中进行少量更改。例如:
#include <sstream>
// ...
QFile outfile(outpath);
if (!outfile.open(QIODevice::WriteOnly | QIODevice::Text
| QIODevice::Truncate))
{
qWarning("Could not open ASCII for writing!");
return false;
}
/* compute XYZ precision */
int prec[3] = {0, 0, 0};
std::ostringstream out;
out.precision(3);
std::fixed(out);
// I assume config.delimiter is a QChar.
char del = config.delimiter.toLatin1();
/* 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.precision(prec[0]);
out << pt->getXYZ(0);
out.precision(prec[1]);
out << del << pt->getXYZ(1);
out.precision(prec[2]);
out << del << pt->getXYZ(2);
out.precision(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";
// Write out the data and empty the stream.
outfile.write(out.str().data(), out.str().length());
out.str("");
}
outfile.close();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3048 次 |
| 最近记录: |