最近在做三维扫描相关项目。利用Sick的三维扫描仪扫描隧道轮廓,并保存成文件。
项目中需要做点云显示和切片。在读取文件时发现性能不高,代码如下:
QFile file("20170930092902.txt");
if (!file.open(QFile::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
int cnt = 0;
while (!in.atEnd()) {
QString line = in.readLine();
QStringList list = line.split(" ");
point[cnt][0] = list.at(0).toFloat();
point[cnt][1] = list.at(1).toFloat();
point[cnt][2] = list.at(2).toFloat();
cnt++;
}
该文本文件总共295723行,8.3M。执行完本段代码用时2.43523 ss。
加上显示和切片等耗时,感觉这代码性能好低,于是准备开始优化。
方法一:将readLine改成readAll方法。
QFile file("20170930092902.txt");
if (!file.open(QFile::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
QString ramData = in.readAll();
QStringList list = ramData.split("\n");
QStringList list1;
int cnt = 0;
for(int i=0; i<list.count()-1; i++)
{
list1 = list.at(i).split(" ");
point[cnt][0] = list1.at(0).toFloat();
point[cnt][1] = list1.at(1).toFloat();
point[cnt][2] = list1.at(2).toFloat();
cnt++;
}
优化完以后,本段代码执行时间为2.20287 s。
有改进,但优化不大。后来单独测试了readAll()和readLine的方法。读取整个文件readAll()耗时0.217646 s;readLine()耗时0.482322 s。确实优化力度不大。
而且整个性能的瓶颈应该不在读取文件,而在于字符串分割和字符串转Float。于是开始想着使用C库函数strtok和atof。于是修改代码如下:
QFile file("20170930092902.txt");
if (!file.open(QFile::ReadOnly | QIODevice::Text))
return;
uchar* fpr = file.map(0, file.size());
int cnt = 0;
int subcnt = 0;
char *substr;
char *s = strdup((char*)fpr);
while(substr= strsep(&s, "\n"))
{
char *lineSubStr;
subcnt = 0;
while(subcnt < 3)
{
lineSubStr = strsep(&substr, " ");
point[cnt][subcnt] = atof(lineSubStr);
subcnt++;
}
cnt++;
}
测试用时0.36724 s(其中map函数用时0.000997 s)。优化成功。(代码中使用strsep而非strtok函数,是因为strtok不支持嵌套使用。)