3

私は次のように定義されたオブジェクトを持っています:

std::unordered_map<std::string, std::vector<int>> large_obj;

非常に大量のデータ(多くの行を含む)を格納でき、非常にうまく機能します。ただし、ファイルにバックアップしたいのでlarge_obj、しばらくしてから、ファイルから別のオブジェクトに再度ロードします。

事前定義された構造でファイルの各行を書き込む代わりに、このオブジェクトを読み書きするための最も最適化された方法は何ですか?

次のことを念頭に置いてください。

  • read()への複数の呼び出しは、単一の呼び出しよりもコストがかかります
  • バイナリファイルはテキストファイルよりも高速です。

オブジェクトI/Oの時間を節約するのはどれですか?

4

3 に答える 3

1

read()andのオーバーヘッドについてはあまり気にしません。write()バッファリングされたストリームと、データ ストリーム内をスキップせずに読み書きできるデータ形式を使用するだけです。

書き出すシリアル化されたストリームは、データ表現に十分近い必要があるため、単純なコピーで大量のデータを引き継ぐことができますが、古いバージョンのデータ形式から再構築したり、内部表現が異なるマシン上で再構築したりできるほど抽象的である必要があります。 .

私は通常、マジック ナンバー、データ形式のバージョン、およびマシン固有の部分をキャプチャする一連の値を含むヘッダーを定義します。あなたの場合、それは

struct header {
    char magic[4];
    uint32_t endianness;           // 0x01020304
    uint32_t version;              // incremented when format changes
    // paranoia
    uint8_t char_bit;              // std::numeric_limits<char>::digits
    // sizeofs for all types format is dependent on
    uint8_t sizeof_int;            // sizeof(int)
};

データを読み戻すときは、ヘッダーの値を予想と比較します。これが一致しない場合は、これを処理する逆シリアル化コードを追加できます。

行については、次のようなエンコーディングを使用します

uint16  string_length;
char    string_data[];        // string_length bytes, padding if odd
uint16  vector_length;
int     vector_data[];        // vector_length ints

これにより、効率的に保存および復元できます。要件が変更された場合は、バージョン番号を増やし、新しい形式を定義し、パーサー コードを適応させて新しいメモリ内表現を作成します。

于 2012-10-22T07:13:27.907 に答える
1

Boost::serializationを試すことができます。ただし、このライブラリには下位互換性がないことに注意してください。シリアル化後、すべてのアーカイブ データをファイルに書き込むことができます。


シリアル化のネイティブな方法は、ストリーム オペレーターを使用することです。これはboost::serilization、ほとんどの内部でどのように機能するかです。クラス メンバー<<>>演算子をオーバーロードして、テキスト形式に読み書きすることができます。ただし、エレガントで安定したソリューションを使用することをお勧めします。

于 2012-10-22T06:30:55.073 に答える
0

おそらく、文書データベースを試すことができます。データベース エンジンは、パフォーマンスの一部を処理します。たとえば、MongoDB 。

最も最適化された方法を持つことは不可能です。トレードオフを考慮し、パフォーマンスを測定する必要があります。Boost.Serialization は優れた代替手段ですが、明確な一連の要件と、最も一般的なユース ケースの少なくともいくつかのパフォーマンス測定値が必要です。

于 2012-10-22T07:10:30.203 に答える