gpt4 book ai didi

qt - 如何使用 QTextStream 优化 ASCII 输出

转载 作者:行者123 更新时间:2023-12-03 16:11:07 32 4
gpt4 key购买 nike

我目前正在将数十亿条二进制记录写入 ASCII 文件(呃)。我已经一切正常,但如果可以的话,我想优化性能。问题是,用户可以选择任意数量的字段进行输出,因此我无法在编译时知道它们将包含 3-12 个字段中的哪一个。

有没有更快的方法来构造 ASCII 文本行?如您所见,字段的类型差异很大,我想不出解决一系列 if() 语句的方法。输出 ASCII 文件每条记录一行,所以我尝试使用模板 QString用 arg 构建,但这只会使速度减慢约 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();

最佳答案

(这不回答分析器问题。它试图回答原始问题,即性能问题。)

我建议在这种情况下完全避免使用 QTextStream 以查看是否有帮助。它可能有助于提高性能的原因是涉及开销,因为文本是 encoded internally to 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();

关于qt - 如何使用 QTextStream 优化 ASCII 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17115640/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com