2

私は小さなデバイスに取り組んでおり、PC ソフトウェアから生成されたかなり大きな構成パラメーター (~100 KB) のセットを持っています。これまでは、パラメータをバイナリ ファイルに保存し、データ構造にロードしていました。メンテナンスは少し面倒です (言語が異なる、構造内のフィールドの順序が一致する、バージョンが異なるなど)。そのため、Google プロトコル バッファへの移行を検討しています。

小さなデバイスの観点から、シリアル化されたプロトコル バッファーを格納するために必要なメモリ領域が気になります。私は C で作業しているので、protobuf-embedded-cをダウンロードしてサンプルの作業を開始しました。計算中のバッファの最大サイズには少し驚きました。たとえば、以下は空のバッファーのサイズであり、名前付きの型の単一の変数を含むバッファーのサイズです。

#define MAX_M_Empty_SIZE 2
#define MAX_M_double_SIZE 12
#define MAX_M_float_SIZE 8
#define MAX_M_int32_SIZE 14
#define MAX_M_int64_SIZE 14
#define MAX_M_uint32_SIZE 9
#define MAX_M_uint64_SIZE 14
#define MAX_M_sint32_SIZE 9
#define MAX_M_sint64_SIZE 14
#define MAX_M_fixed32_SIZE 8
#define MAX_M_fixed64_SIZE 12
#define MAX_M_sfixed32_SIZE 8
#define MAX_M_sfixed64_SIZE 12
#define MAX_M_bool_SIZE 5

構造体に「int32」を追加するたびに、最大サイズが 14 バイト増加しました。これにはキーが含まれており、おそらくバリアントのエンコーディングの最悪のケースが含まれていることはわかっていますが、今後何が期待できますか? 大きなメッセージは小さなメッセージよりも効率的ですか、それともエンコードされた値に依存していますか?

要約すると、プロトコル バッファのメモリ空間の使用状況を把握しようとしているだけです。構成データを格納するために必要なメモリ領域が大幅に増加するために、使いやすさを犠牲にすることはできません。ありがとう!

4

2 に答える 2

2

int32varintとして記述されます。これは、正の値の場合、必要なスペースが大きさに依存することを意味します。小さな正の値はシングルバイトにすることができます。正の値が大きいほど、より多くの時間がかかる可能性があります。負の値は、より多くのスペースを必要とします。特に、非常に大きな64ビット数と同じです。「varint」は7ビットプラス継続です。したがって、負の数(または大きな正の数)は10バイトかかる可能性があります。これを回避するには、値が負になる可能性があることがわかっている場合は、sint32/を使用できます。sint64これは、ジグザグエンコーディング(次にvarint)を使用します。これにより、基本的に、小さいマグニチュード値は大きいマグニチュード値よりも少ないスペースで済みます(符号に関係なく)。

最悪の場合に最適化する必要がある場合は、代わりにfixed32/を使用することを検討してください。fixed64これにより、正確に4バイトまたは8バイトを取ることが保証されます。

概要:

  • 常に(またはほとんど常に)ポジティブで、一般的に小から中程度のサイズ:int32/int64
  • 正または負、および一般的に小から中程度の大きさ:sint32/sint64
  • 値が大きい場合、またはサイズを保証する必要がある場合:fixed32/fixed64

他にもいくつかあります。詳細は言語ガイドにあります

(上記のすべての場合、ヘッダーも含める必要がありますが、通常は1バイトまたは2バイトです)

于 2012-11-13T20:04:37.003 に答える
1

Nanopb は非常に小さなメモリ空間で動作し、メモリ バッファの必要性を回避するためにファイルとの間で直接シリアル化することもできます: http://koti.kapsi.fi/jpa/nanopb/

于 2012-11-14T06:59:36.147 に答える