2

tag = valueとして記述されたデータファイルがいくつかあります。ここで、tagは文字列であり、valueは数値、文字列、配列などです。読みやすく、簡単に編集できるため、この形式を使用します。これで、この形式を使用してインスタンス化されるすべてのクラスにloadメソッドがあり、必要なタグを読み取り、これらのタグ内にある値を使用します。読み込み速度を上げるためにデータをバイナリにしたい。1つの方法は、すべてのクラスにToBinary(名前は関係ありません)メソッドを設定し、古いデータを読み取ってファイルに書き込み、新しいファイルを使用してオブジェクトをインスタンス化することです。これはオフラインで、1回/アプリケーションでのみ実行できます。これについて他に提案はありますか?これにはC++を使用します。

編集:今最も費用のかかる部分は、最初にファイルを読み取ったときにファイルを解析し、その後、ディスクからファイルを読み取るのではなく、必要なタグを検索することだと思います。カスタムファイルシステムを使用して、1つの大きなファイルに複数の小さなファイルを含めることができます。

4

6 に答える 6

1

I haven't used it before, but I'm sure Boost's Serialization module is a good place to start.

于 2011-03-16T14:31:57.297 に答える
1

ファイルを使用している場合、ファイルに保存するデータのチャンクが非常に大きい場合 (画像、ビデオなど) を除いて、バイナリ データを使用してもおそらくパフォーマンスは大幅に向上しません。

ただし、 Boostのようなバイナリ シリアライゼーション アルゴリズムを使用することはできます。

于 2011-03-16T14:34:08.123 に答える
1

このためのシリアライゼーション基本クラスがあり、バージョン処理を埋め込むことができる小さなヘッダーを持つ To/From 関数があります。ローカルに保存する必要があり、ほとんどの場合「読み取り専用」の単純なデータに適したシステムだと思います。

このようなもの:

class SeralizeMe
{
public:

 virtual bool To(Archive &file)=0;
 virtual bool From(Archive &file)=0;

 virtual bool NeedsSave(void)=0;

};

ただし、次の場合はこのシステムを使用しないでください。

  • 頻繁にフォーマットを変更する必要があります。
  • ロードするデータと保存するデータを選択する必要があります。
  • 保存中の停電に特に敏感な大きなファイルを使用してください。

上記のいずれかに該当する場合は、データベースを使用してください。FirebirdSQL 組み込みが適切な候補です。

于 2011-03-16T14:35:03.007 に答える
0

もう 1 つは、Google の protobuf です。最速ではありませんが、進化するデータ型をサポートでき、ネットワーク上で非常に効率的で、他の言語をサポートします。

ここにリンクします。

于 2011-03-16T14:34:24.663 に答える
0

パフォーマンスを向上させたい場合は、固定長フィールドを使用する必要があります。可変長フィールドを解析またはロードしても、パフォーマンスが大幅に向上するわけではありません。テキスト行ごとの読み取りには、行末トークンのスキャンが含まれます。スキャンは時間を無駄にします。

次の提案を使用する前に、コードをプロファイリングして、パフォーマンスのベースライン時間または数値を確立します。各最適化のパフォーマンス デルタを計算できるようになるため、各提案の後にこれを行います。私の予測では、各最適化でデルタが小さくなるということです。

最初にファイルを固定長レコードに変換し、引き続きテキストを使用することをお勧めします。必要に応じてフィールドをスペースで埋めます。したがって、レコードのサイズがわかれば、メモリへの読み取りをブロックして、メモリを配列として扱うことができます。これにより、大幅な改善が得られるはずです。

この時点で、ボトルネックは依然としてファイル I/O 速度であり、(ファイル I/O は OS によって制御されているため) 実際には大幅な改善はできません。また、テキストのスキャン/変換です。テキストを数値に変換し、最後にバイナリに変換します。 何としても、データ ファイルを人間が読める形式に保つことをお勧めします。

データ ファイルを読みにくくする前に、アプリケーションをスレッドに分割してみてください。1 つのスレッドが GUI を処理し、別のスレッドが入力を処理し、別のスレッドが処理を処理します。アイデアは、プロセッサが待機するのではなく、コードの一部を常に実行することです。最新のプラットフォームでは、CPU がコードを処理している間にファイル I/O を実行できます。

移植性を気にしない場合は、プラットフォームに DMA 機能があるかどうかを確認してください (DMA またはダイレクト メモリ アクセス コンポーネントを使用すると、プロセッサを使用せずに、またはプロセッサの使用を最小限に抑えてデータを転送できます)。注意すべき点は、多くのプラットフォームがプロセッサと DMA の間でアドレスとデータ バスを共有していることです。したがって、一方のコンポーネントがブロックまたは一時停止され、もう一方のコンポーネントがアドレス バスとデータ バスを使用します。したがって、役立つ場合とそうでない場合があります。プラットフォームの配線方法によって異なります。

key フィールドを変換して、数値、別名tokensを使用します。トークンは数値であるため、ジャンプ テーブル (switch ステートメントも) へのインデックスとして、または単に配列へのインデックスとして使用できます。

最後の手段として、ファイルをバイナリに変換します。バイナリ バージョンには、トークンとしてのキーと値の 2 つのフィールドが必要です。データを大きなチャンクでメモリに取り込みます。

概要

  1. 大きなデータ ブロックをメモリに移動します。
  2. ベースラインのパフォーマンス測定値を確立するために変更を行う前にプロファイリングします。
  3. 最適化ごとにプロファイリングを行い、一度に 1 ステップずつ最適化します。
  4. 人間が読める形式でデータ ファイルを保持することを好みます。
  5. データ ファイルへの変更を最小限に抑えます。
  6. 固定長フィールドを使用するようにファイルを変換します。
  7. アプリケーションが待機しないように、スレッドまたはマルチタスクを使用してみてください。
  8. テキストを数値トークンに変換します (人間の可読性を低下させます)
  9. 最後の手段としてデータをバイナリに変換します (人間が読み取りとデバッグを行うのは非常に困難です)。
于 2011-03-16T17:43:09.907 に答える
0

2 つのアイデアがあります。

1) タグのリストが定数であり、事前にわかっている場合は、それぞれを BYTE (または WORD) に変換し、その後に値の長さ (バイト単位)、その後に値の生の c-string を続けることができます。ペイロード。

たとえば、次の場合:

Tag1 = "hello World!" // 12 bytes in length (achieved by "strlen(value) * sizeof(char)" )
Tag2 = "hello canada!"  // 13 bytes in length 

これをバイト ストリームに変換できます。

0x0001 0x000B // followed by 12 bytes representing the 'value' // 0x0002 0x000C // followed by 13 bytes representing 'value2'

プログラムは、WORD ヘッダー "0x0001" が Tag1 を表し、ヘッダー "0x0002" が Tag2 を表していることを知るだけで済みます。

タグ名が事前にわからない場合は、同様の長さ、値の構造に従って、タグ名をさらに抽象化することもできます。

2) おそらく遅いビットは、テキスト解析の実装にすぎませんか? やろうとしていることに専用のオープンソース ライブラリを使用することを検討してください。例: " boost::property_tree "

プロパティ ツリーは、キーと値のペアを格納および取得するように特別に設計されています (構成設定ファイルとして使用するように設計されています)。しかし、これを経済的にするために保存しようとしているそのようなペアの数に依存すると思います.

于 2011-03-16T19:57:58.033 に答える