1

テキスト ファイルを構造体の配列に読み込む必要があります。既にプログラムを作成しましたが、ファイル内に約 13 個の lac 構造体があるため、時間がかかりすぎています。C ++でこれを行うための最善かつ最速の方法を提案してください。

ここに私のコードがあります:

std::ifstream input_counter("D:\\cont.txt");

/**********************************************************/
int counter = 0;
while( getline(input_counter,line) )
{
    ReadCont( line,&contract[counter]); // function to read data to structure
    counter++;
    line.clear();
}
input_counter.close();
4

4 に答える 4

1

QFile::readAll()メモリの問題を引き起こす可能性があり、std::getline()低速です (現状のまま::fgets())。

非常に大きな区切りテキスト ファイルを .xml ファイルで解析する必要があるという同様の問題に直面しましたQTableView。カスタム モデルを使用して、ファイルを解析し、各行の先頭へのオフセットを見つけました。次に、テーブルにデータを表示する必要がある場合は、行を読み取り、必要に応じて解析します。これにより、多くの解析が行われますが、実際には、スクロールや更新速度の遅延に気付かないほど十分に高速です。

また、ファイルの内容をメモリに読み込まないため、メモリ使用量が少ないという利点もあります。この戦略では、ほぼすべてのサイズのファイルが可能です。

解析コード:

m_fp = ::fopen(path.c_str(), "rb"); // open in binary mode for faster parsing
if (m_fp != NULL)
{
  // read the file to get the row pointers
  char buf[BUF_SIZE+1];

  long pos = 0;
  m_data.push_back(RowData(pos));
  int nr = 0;
  while ((nr = ::fread(buf, 1, BUF_SIZE, m_fp)))
  {
    buf[nr] = 0; // null-terminate the last line of data
    // find new lines in the buffer
    char *c = buf;
    while ((c = ::strchr(c, '\n')) != NULL)
    {
      m_data.push_back(RowData(pos + c-buf+1));
      c++;
    }
    pos += nr;
  }

  // squeeze any extra memory not needed in the collection
  m_data.squeeze();
}

RowDataおよびm_data私の実装に固有のものですが、ファイル内の行に関する情報 (ファイルの位置や列の数など) をキャッシュするためにのみ使用されます。

私が採用したもう 1 つのパフォーマンス戦略はQByteArrayQString. Unicode データが必要でない限り、これにより時間とメモリが節約されます。

// optimized line reading procedure
QByteArray str;
char buf[BUF_SIZE+1];
::fseek(m_fp, rd.offset, SEEK_SET);
int nr = 0;
while ((nr = ::fread(buf, 1, BUF_SIZE, m_fp)))
{
  buf[nr] = 0; // null-terminate the string
  // find new lines in the buffer
  char *c = ::strchr(buf, '\n');
  if (c != NULL)
  {
    *c = 0;
    str += buf;
    break;
  }
  str += buf;
}

return str.split(',');

各行を 1 文字ではなく文字列で分割する必要がある場合は、 を使用します::strtok()

于 2013-09-04T14:53:49.970 に答える
1

「解析」をできるだけ単純に保ちます。たとえば、フィールドの形式を知っている場合は、その知識を適用します

ReadCont("|PE|1|0|0|0|0|1|1||2|0||2|0||3|0|....", ...)

次のような高速文字を整数変換に適用する必要があります

ReadCont(const char *line, Contract &c) {
   if (line[1] == 'P' && line[2] == 'E' && line[3] == '|') {
     line += 4;
     for (int field = 0; field < K_FIELDS_PE; ++field) {
       c.int_field[field] = *line++ - '0';
       assert(*line == '|');
       ++line;
     }
   }

まあ、詳細に気をつけてください、しかしあなたはアイデアを得ました...

于 2013-09-03T09:09:41.997 に答える