有一个文本文件最多可能包含 5*10^6
个二维点。
在对读取该文件的代码进行了一些测量和测试后,我发现瓶颈在于我使用 QString::split
函数将读取的行拆分为多个部分,如下所示:
QString x, y; QStringList lineParts;
while (!inputSream.atEnd())
{
line = inputSream.readLine();
if (line.size() > 0)
{
if (! line.contains("#"))
{
>> lineParts = line.split(' ', QString::SkipEmptyParts); // performance go down by a almost ~2 seconds
x = lineParts.at(0);
y = lineParts.at(1);
QPointF p;
qreal yd = y.toDouble();
p.setX(x.toDouble());
p.setY(yd);
if (yd < yRanges.first)
yRanges.first = yd; // minY
if (yd > yRanges.second)
yRanges.second = yd; // maxY
points.push_back(p);
} else
{
headers.push_back(line);
}
}
}
如果没有这个函数,它读取文件的速度几乎快 2 倍
为什么 QString
拆分操作这么慢?
如何在不编写自己的拆分函数的情况下提高此操作的性能?
附注
我正在考虑用 2 个线程将整个文件读取分开,其中一个线程将行读入缓冲区并为对应的槽发出文件读取完成信号,该槽会用这些点做一些其他事情。
但这对我来说听起来有点开销而且没有性能提升,因为它不会有太大差异,因为它仍然会进行同步操作,即:“当行未被读取时,它无法被解析”因此我认为最好对字符串进行更快的拆分
最佳答案
如果您使用的是Qt5.4及以上版本,
使用“QString::splitRef
”。这样会更快。
split
返回,将子字符串复制到 Qstring
列表中。这会增加内存分配的负担。
splitRef
将子字符串引用(仅数据拷贝)返回到 QStringRef
的 vector 中。这避免了内存分配的负担,因为只返回引用。
文档说:“此类(QStringRef)旨在提高处理从现有 QString 实例中获取的子字符串时的子字符串处理性能。QStringRef 通过简单地引用来避免标准 QString 的内存分配和引用计数开销原始字符串的一部分。 "
http://doc.qt.io/qt-5/qstringref.html#details
注意:您应该注意原始字符串的生命周期或范围。“只要此字符串还存在,所有引用都是有效的。破坏此字符串将导致所有引用都是悬挂指针。” http://doc.qt.io/qt-5/qstring.html#splitRef
关于c++ - 使用 QString::split 函数时性能下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43021084/