QT 讀取大量點雲文件的性能優化


  最近在做三維掃描相關項目。利用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不支持嵌套使用。有時間的話會在下篇隨筆中詳細解釋) 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM