2017-03-01 9 views
1

私はprotobuf-netでシリアライズされたファイルの最終的なサイズを把握しようとしていますので、最良の方法を選択できます。protobufファイルサイズを計算するには?

私は、さまざまなプロト構成とバイナリシリアル化を使っていくつかの比較テストを行いましたが、 "varint to bytes"変換がどのように動作するかはまだ分かりません。

クラス

public class Pt2D 
{ 
    public Pt2D() { } 

    public Pt2D(double x, double y) 
    { 
     X = x; 
     Y = y; 
    } 
    public double X { get; set; } 

    public double Y { get; set; } 
} 

public class Pt3D : Pt2D 
{ 
    public Pt3D() { } 

    public Pt3D(double x, double y, double z) : base(x, y) 
    { 
     Z = z; 
    } 
    public double Z { get; set; } 
} 

public class FullPt3D 
{ 
    public FullPt3D() { } 

    public FullPt3D(double x, double y, double z) 
    { 
     X = x; 
     Y = y; 
     Z = z; 
    } 

    public double X { get; set; } 

    public double Y { get; set; } 

    public double Z { get; set; } 
} 

テストケース

private void ProtoBufferTest() 
{    
    var model = RuntimeTypeModel.Default; 

    model.Add(typeof(Pt2D), false) 
     .Add(1, "X") 
     .Add(2, "Y") 
     .AddSubType(101, typeof(Pt3D)); 

    model[typeof(Pt3D)] 
     .Add(1, "Z"); 

    model.Add(typeof(FullPt3D), false) 
     .Add(1, "X") 
     .Add(2, "Y") 
     .Add(3, "Z"); 

    double x = 5.6050692524784562; 
    double y = 0.74161805247031987; 
    double z = 8.5883424750474937; 

    string filename = "testPt3D.pb"; 
    using (var file = File.Create(filename)) 
    { 
     Serializer.Serialize(file, new Pt3D(x, y, z));        
    } 
    Console.WriteLine(filename + " length = " + new FileInfo(filename).Length + " bytes") ; 

    filename = "testFullPt3D.pb"; 
    using (var file = File.Create(filename)) 
    { 
     Serializer.Serialize(file, new FullPt3D(x, y, z));     
    } 
    Console.WriteLine(filename + " length = " + new FileInfo(filename).Length + " bytes"); 

    filename = "testBinaryWriter.bin"; 
    using (var file = File.Create(filename)) 
    { 
     using (var writer = new BinaryWriter(file)) 
     {     
      writer.Write(x); 
      writer.Write(y); 
      writer.Write(z); 
     } 

    } 
    Console.WriteLine(filename + " length = " + new FileInfo(filename).Length + " bytes"); 


}  

テスト結果

1)testPt3D.pb長= 30バイト

2)testFullPt3D.pb長= 27バイト

3)testBinaryWriter.bin長= 24バイト

24バイトは、3つのダブル値を格納するために使用され、それはOKですが、どのような値がケース1内に格納されている)、2)30及び27バイトに到達するQ1) ? testPt3D.pb長=:私はPt2Dのためのサブタイプのマッピングを変更することにより、いくつかのテストをしたが、私はサイズが

model.Add(typeof(Pt2D), false) 
     .Add(1, "X") 
     .Add(2, "Y") 
     .AddSubType(3, typeof(Pt3D)); 

の検索結果を変える理解できない

Q2)(私はモデルマッピングで使用されるint型の値を仮定します) 29バイト

model.Add(typeof(Pt2D), false) 
     .Add(1, "X") 
     .Add(2, "Y") 
     .AddSubType(21, typeof(Pt3D)); 

結果:testPt3D.pb長= 30バイト

model.Add(typeof(Pt2D), false) 
     .Add(1, "X") 
     .Add(2, "Y") 
     .AddSubType(1111, typeof(Pt3D)); 

結果:testPt3D.pb長さ= 30バイト

私はthis toolを使いこなそうとしましたが、別のバイト変換結果が得られました。

なぜ21,101,1111を使用して同じサイズになるのですか?

+0

これに関する手がかりはまだありますか? :( – ilCosmico

答えて

1

1)testPt3D。pb長= 30バイト

  • (サブクラスが最初に来る)[フィールド101、文字列] = 2バイト、 "文字列"の場合は3ビット、 "101"の場合は7ビット。 varintので、継続ビットと7ビット単位でパック:2バイト(合計= 2)
    • [データ長 "9"] = 1バイト(合計= 3)
    • [フィールド1、64を固定] = 1バイト(合計= 4)
    • [ペイロード1] = 8バイト(合計= 12)
  • [フィールド1、固定64] = 1バイト(合計= 13)
  • [ペイロード1 ] = 8バイト(合計= 21)
  • [フィールド2、固定64] = 1バイト(合計= 22)
  • [ペイロード2]は8バイト(合計= 30)

2)testFullPt3D.pb長= 27バイト

  • [フィールド1、固定64] = 1バイト(合計= 1)=
  • [ペイロード1] = 8バイト(合計= 9)
  • [フィールド2、固定64] = 1バイト(合計= 10)
  • [ペイロード2] = 8バイト(合計= 18)
  • [フィールド3、固定64] = 1b YTE(合計= 19)
  • [ペイロード3] = 8バイト(合計= 27)

繰り返しデータを扱う場合いるProtobufの他のオプションがある - "パック" とは、 "グループ化"。ただし、については、のデータを3つの値よりも議論するときにのみ意味があります。

+0

私はフィールドやサブクラスを識別するために使用するインデックス値は、サイズには影響しません?(私の最後の質問を参照してください - なぜ21,101または1111を使用して同じサイズを取得しますか?) – ilCosmico

+0

@ ilCosmicoフィールド番号は7ビットのチャンクでパックされていますが**最初のバイトの** 3ビットは既に使用されています(ワイヤタイプの場合) - 最初のチャンクの4ビットのみが使用可能です。 1〜15(4ビット)の1バイトマーカー、その後7ビットの次のチャンクを使用して、5〜11ビット(フィールド16〜2047)の2バイトマーカーを取得します。あなたが "2500"を選択した場合、3バイトかかるでしょう –

+0

もう一度、ありがとう、今それはより明確です:) – ilCosmico

関連する問題