30

私は最近、メッセージでさまざまなスカラー値の型を使用できるようにするGoogle Protocol Buffersについて調べています。

彼らのドキュメントによると、可変長整数プリミティブint32には 、uint32、およびの 3 種類がありますsint32。彼らのドキュメントでint32は、「負の数をエンコードするには非効率的です。フィールドに負の値が含まれる可能性がある場合は、sint32代わりに使用してください。」しかし、負の数を持たないフィールドがある場合は、とにかく uint32 を使用する方が適していると思いますint32(余分なビットと負の数を処理するための CPU コストの削減のため)。

では、いつint32使用するのに適したスカラーになるのでしょうか? ドキュメントは、負の数がめったに得られない場合にのみ最も効率的であることを暗示していますか? または、フィールドの内容に応じて、常にsint32andを使用することをお勧めしますか?uint32

(これらのスカラーの 64 ビット バージョンにも同じ質問が適用されます: int64uint64、およびsint64; しかし、読みやすくするために、問題の説明からそれらを除外しました。)

4

2 に答える 2

42

私は Google Protocol Buffers に精通していませんが、ドキュメントの私の解釈は次のとおりです。

  • uint32値が負にならない場合に使用します
  • sint32値が負である可能性が高い場合とそうでない場合に使用します(「可能性が高い」というあいまいな定義の場合)
  • int32値が負になる可能性があるが、値が正である可能性ははるかに低い場合に使用します (たとえば、アプリケーションがエラーまたは「不明な」値を示すために -1 を使用する場合があり、これは比較的まれな状況です) 。

エンコーディングに関するドキュメントの説明は次のとおりです ( http://code.google.com/apis/protocolbuffers/docs/encoding.html#types ):

負の数のエンコードに関しては、signed int 型 (sint32およびsint64) と「標準」の int 型 (int32および)の間には重要な違いがあります。負の数の型としてorint64を使用すると、結果は常に 10 バイトの長さになります。これは、事実上、非常に大きな符号なし整数のように扱われます。符号付きタイプのいずれかを使用すると、結果ははるかに効率的な ZigZag エンコーディングを使用します。int32int64varintvarint

ZigZag エンコーディングは、符号付き整数を符号なし整数にマップするため、絶対値が小さい (-1 など)varint数値もエンコードされた値が小さくなります。これは、-1 が 1 としてエンコードされ、1 が 2 としてエンコードされ、-2 が 3 としてエンコードされるように、正と負の整数を前後に「ジグザグ」する方法で行われます...

したがって、負の数の使用がまれであっても、プロトコルで渡す数値 (非負の数を含む) の大きさが小さい側にある限り、 を使用した方がよい場合がありますsint32。よくわからない場合は、プロファイリングが適切です。

于 2009-04-19T20:51:02.760 に答える