0

だから私はSQLite3データベースに変換したようなCSV形式の1GBファイルを持っています

column1;column2;column3
1212;abcd;20090909
1543;efgh;20120120

12列あることを除いて。ここで、このデータを読み取って並べ替え、出力用に再フォーマットする必要がありますが、これを実行しようとすると、(ベクターを使用して) RAM が不足しているように見えます。私はそれを SQLite から読み込み、ファイルの各行を構造体に格納し、それを両端キューにプッシュします。私が言ったように、RAM の使用量が 2GB に近づくとメモリが不足し、アプリがクラッシュします。STXXL を使用してみましたが、POD 以外の型のベクトルをサポートしていないようです (したがって、long int、double、char などである必要があります)。価値。

基本的に、特定の列に同じ値を持つすべての「行」をグループ化する必要があります。つまり、1 つの列に基づいてデータを並べ替えてから、それを操作する必要があります。

すべてを読み取る方法、または少なくとも並べ替える方法についてのアプローチはありますか? 私は SQLite3 でそれを行いますが、時間がかかるようです。おそらく私は間違っています。

ありがとう。

4

5 に答える 5

1

望ましい順に並べると、次のようになります。

  1. C++ をまったく使用せず、可能であればソートのみを使用してください
  2. DB を使用してそれほど大きくない csv ファイルを処理することに慣れている場合は、実際にはリレーショナルではないように思えますが、すべての面倒な作業を DB に移し、メモリ管理について心配させてください。
  3. C++ で行う必要がある場合:
    • 何にも使用していないため、SQLite3 の手順は完全にスキップしてください。csv ファイルをメモリにマップし、行ポインタのベクトルを作成するだけです。データを移動せずにこれを並べ替える
    • 行を構造に解析する必要がある場合:
      • 文字列列を次のように保存しないでくださいstd::string。これには、追加の非連続割り当てが必要であり、メモリが浪費されます。長さが制限されている場合は、インライン char 配列を優先します
      • 値に適合する最小の整数サイズを選択します (たとえば、uint16_t はサンプルの最初の列の値に適合します)。
      • パディングに注意してください。構造体のサイズを確認し、メンバーを並べ替えるか、予想よりもはるかに大きい場合はパックします
于 2014-03-20T18:49:11.923 に答える
0

ご回答ありがとうございますが、非常に高速でシンプルなアプローチを見つけました。

次のクエリを指定して、SQLite3 に仕事を任せます。

SELECT * FROM my_table ORDER BY key_column ASC

処理に約 70 秒かかった 800MB のファイルの場合、C++ プログラムですべてのデータを受け取りました。これらのデータは、グループ化したい列で既に並べ替えられており、一度に 1 つのグループで列を処理し、それらを出力しました。目的の出力形式で一度に 1 つずつ、RAM が過負荷にならないようにします。操作の合計時間は約 200 秒で、これにはかなり満足しています。

お時間をいただきありがとうございます。

于 2014-03-21T19:36:30.920 に答える