1

私はいくつかのプロジェクトに取り組んでおり、ファイルから膨大な量のデータを読み取るのに最も効率的な方法はどれか疑問に思っています (100 行から最大 30 億行のファイルについて話しています。 )。読み取られると、データは構造化されたデータ セットに格納されます ( vector<entry>「エントリ」は構造化された行を定義します)。

このファイルの構造化された行は次のようになります: string int int int string string これも適切なプラットフォームで終わり、EOLタブで区切られています

私が達成したいのは:

  1. ファイルをメモリに読み込む ( string) またはvector<char>
  2. バッファから生データを読み取り、それをデータセットにフォーマットします。

メモリ フットプリントを考慮し、解析速度を速くする必要があります。stringstream遅すぎるように見えるので、私はすでに の使用を避けています。

また、次を使用して、ファイルへの複数の I/O 呼び出しを回避しています。

// open the stream
std::ifstream is(filename);

// determine the file length
is.seekg(0, ios_base::end);
std::size_t size = is.tellg();
is.seekg(0, std::ios_base::beg);

// "out" can be a std::string or vector<char>
out.reserve(size / sizeof (char));
out.resize(size / sizeof (char), 0);

// load the data
is.read((char *) &out[0], size);

// close the file
is.close();

この巨大なstd::stringデータを 1 行ずつループして、行情報 (文字列と整数部分) をデータ セットの行に抽出することを考えました。これを行うより良い方法はありますか?

編集 : このアプリケーションは、32 ビット、64 ビットのコンピューター、またはより大きなファイル用のスーパー コンピューターで実行できます。

どんな提案でも大歓迎です。

ありがとうございました

4

2 に答える 2

0

私は 3 つのギガビット ラインを備えたスーパーコンピューターについて話すことはできませんが、デスクトップ マシンのメモリではどこにも行きません。

まず、そのデータに対するすべての操作を理解しようとする必要があると思います。すべてのアルゴリズムが順次動作するように設計する必要があります。ランダムアクセスが必要な場合は、常にスワッピングを行います。このアルゴリズム設計は、データ モデルに大きな影響を与えます。

簡単な部分だからといって、すべてのデータを読み取ることから始めるのではなく、処理全体でどのデータがメモリにあるかを明確に表示してシステム全体を設計してください。


ストリーム上
ですべての処理を 1回の実行で実行し、データ処理をステージ (読み取り - 前処理 - ... - 書き込み) に分割すると、マルチスレッドを効果的に利用できます。


最後に

  • データのループで何をしたい場合でも、ループの数を最小限に抑えるようにしてください。読み取りループで確実に平均化できます。
  • すぐに、サイズと時間の最悪のケースであると予想されるサイズのテスト ファイルを作成する 2 つの異なるアプローチ

.

time
loop
    read line from disk
time
loop
    process line (counting words per line)
time
loop
    write data (word count) from line to disk
time

対。

time
loop
    read line from disk
    process line (counting words per line)
    write data (word count) from line to disk
time

アルゴリズムがすでにあなたのものを使用している場合。それ以外の場合は、1 つを構成します (1 行あたりの単語数を数えるなど)。書き込み段階が問題に当てはまらない場合は、スキップしてください。このテストを書くのに 1 時間もかかりませんが、大幅に節約できます。

于 2012-12-02T21:44:21.443 に答える
0

いくつかのランダムな考え:

  • 最初に vector::resize() を使用します(あなたはそうしました)
  • ファイル データの大きなブロックを一度に読み取ります。少なくとも 4k、できれば 256k です。それらをメモリ バッファに読み込み、そのバッファをベクトルに解析します。
  • ファイル全体を一度に読み取らないでください。不必要にスワッピングが発生する可能性があります。
  • sizeof(char) は常に 1 です :)
于 2012-12-02T20:49:18.330 に答える