有一个文本文件,最多可能包含5*10^6
个2D点。
经过一些实验测量并使用读取此文件的代码进行测试后,我发现瓶颈在于我使用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
拆分操作这么慢?
如果不编写自己的拆分功能,可以做些什么来提高此操作的性能?
P.S。
我正在考虑将整个文件读取与2个线程分开,其中一个读取行进入一个缓冲区并发出一个相应插槽的文件读取完成信号,该点将用点做其他一些东西。
但是这对我来说听起来有点开销而没有性能提升,因为它不会有太大的不同,因为它仍然会进行同步操作,即:“虽然没有读取行但它不能被解析”因此我认为最好快速拆分字符串
答案 0 :(得分:2)
如果您使用的是Qt5.4及更高版本,
使用“QString::splitRef
”。这会更快。
split
将子字符串的副本返回到Qstring
列表中。这会增加内存分配的负担。
splitRef
将子字符串引用(仅数据副本)返回到QStringRef
的向量中。这样可以避免内存分配的负担,因为只返回引用。
文档说:“此类(QStringRef)旨在提高从现有QString实例获取的子串时子串处理的性能.QStringRef通过简单引用避免了标准QString的内存分配和引用计数开销原始字符串的一部分。“
http://doc.qt.io/qt-5/qstringref.html#details
注意: 您应该注意原始字符串的生命周期或范围。“只要此字符串处于活动状态,所有引用都有效。销毁此字符串将导致所有引用都是悬空指针。“ http://doc.qt.io/qt-5/qstring.html#splitRef