2

現在、ユーザー定義の構造に IsPacked=true を使用できますか? そうでない場合、将来的に計画されていますか?

その属性を ColorBGRA8[] 型のフィールドに適用しようとすると、次の例外が発生します: System.InvalidOperationException : 単純なデータ型のみがパックされたエンコーディングを使用できます

私のシナリオは次のとおりです。私はゲームを書いており、色、ベクトル、行列、頂点、定数バッファーなど、さまざまなものに対して大量の blitable 構造を持っています。それらのメモリ レイアウトは、たとえばシェーダーからの定数バッファー レイアウトと一致させるために、コンパイル時に正確に定義する必要があります (通常、フィールドは 16 バイト境界で整列する必要があります)。

誰かの時間を無駄にするつもりはありませんが、この特定の質問に関する最近の情報は見つかりませんでした。

回答後に編集

現在、protobuf-net を使用するソリューションをテストしていますが、ユーザー定義の大規模な配列を除き、blitable な構造になっています。カスタム構造体の配列のすべてのフィールドは、パック可能なバイト配列に置き換えられました。protobuf-net がデータのデシリアライズを終了したら、p/invoke 経由で memcpy を使用して、カスタム構造の配列を再び操作できるようにします。

次の数値は、byte[] または ColorBGRA8[] のいずれかの 1 つのフィールドを含む 1 つのインスタンスをシリアル化するテストからのものです。生のテストデータは、約 38MiB のデータです。たとえば、カラー配列の 1000000 エントリです。シリアル化は、MemoryStream を使用したメモリ内でのシリアル化でした。


Platform.Copy + Protobuf の書き込み: 51ms、サイズ: 38,15 MiB Protobuf
: 2093ms、サイズ: 109,45 MiB

Platform.Copy + Protobuf の読み取り
: 43ms Protobuf: 2307ms

このテストは、多かれ少なかれランダムなデータの巨大な配列の場合、顕著なメモリ オーバーヘッドが発生する可能性があることを示しています。(デ)シリアル化の時代がなければ、これはそれほど大したことではなかったでしょう。protobuf-net が私の極端なケースに合わせて設計されていない可能性があることは理解していますが、それを受け入れるつもりはありません。

protobuf-net は他のすべてに対して非常にうまく機能するため、このハイブリッド アプローチに固執すると思います。

4

1 に答える 1

4

単純に「当てはまらない」。エンコーディング仕様から引用するには:

プリミティブ数値型 (varint、32 ビット、または 64 ビット ワイヤ型を使用する型) の繰り返しフィールドのみが「パック済み」と宣言できます。

これは、カスタム構造またはクラスでは機能しません。ここで適用される 2 つのアプローチは、文字列 (長さのプレフィックス) とグループ (開始/終了トークン) です。多くの場合、後者はエンコードのコストが低くなりますが、Google は前者を好みます。

Protobuf は、他のバイト レイアウトと任意に一致するようには設計されていません。これは独自のエンコード形式であり、protobuf データを処理/出力するためだけに設計されています。「XML を書いているが、代わりに {non-xml} のように見せたい」と言っているようなものです。

于 2013-04-16T19:16:19.273 に答える