2011-03-18 1 views
1

protobuf-csharp-portに付属の標準アドレス帳のチュートリアルを作成しました。コードは次のとおりです。protobuf-csharp-port - LINQ-to-XMLのaxis関数のようなファイルからのストリーミングレコード

class Program 
{ 
    static void Main(string[] args) 
    { 
     CreateData(); 
     ShowData(); 
    } 

    private static void CreateData() 
    { 
     AddressBook.Builder abb = new AddressBook.Builder(); 
     for (int i = 0; i < 2000000; i++) 
     { 
      Person.Builder pb = new Person.Builder(); 
      pb.Id = i; 
      pb.Email = "[email protected]"; 
      pb.Name = "John" + i; 
      abb.AddPerson(pb.Build()); 
     } 
     var ab = abb.Build(); 
     var fs = File.Create("c:\\testaddressbook.bin"); 
     ab.WriteTo(fs); 
     fs.Close(); 
     fs.Dispose(); 
    } 

    private static void ShowData() 
    { 
     var fs = File.Open("c:\\testaddressbook.bin", FileMode.Open, FileAccess.Read, FileShare.Read); 
     CodedInputStream cis = CodedInputStream.CreateInstance(fs); 
     cis.SetSizeLimit(Int32.MaxValue); 
     AddressBook ab = AddressBook.ParseFrom(cis); 
     Console.WriteLine("Person count: {0}", ab.PersonCount); 
     for (int i = 0; i < ab.PersonCount; i++) 
      Console.WriteLine("Name: " + ab.GetPerson(i).Name); 
     Console.WriteLine("Person count: {0}", ab.PersonCount); 
     fs.Close(); 
    } 
} 

データの書き込み時には、2mレコードに300MBのRAMが必要です。読み込みには約415 MBのRAMが必要です。

XMLの世界では、軸機能を使用して要素をストリーミングします。アドレス帳モデルオブジェクト内のレコードをストリーミングすることは可能ですか?もっと効率的なメモリ使用のためにこれを実装する別の方法がありますか?

おかげ

答えて

2

はい、読み取りと書き込みの両方をストリーミングできます。

公式のJava APIとC#APIでサポートされているバージョンはWriteDelimitedTo/ParseDelimitedFromです。

また、区切られたAPIが来る前に私がAPIに導入したMessageStreamWriterMessageStreamIteratorを使用することもできます。

+0

ありがとう! – krisdyson

1

私はその実装についてのコメント、しかしいるProtobufネットストリーミングで十分可能であることはできません。ストリーミングするすべてのオブジェクトがルートオブジェクトの第1レベルの子である場合は、単純に外側のシーケンスを反復処理できます。それらがすべて同じタイプの場合はSerializer.DeserializeItems<T>を使用します。オブジェクトの種類が異なる場合はSerializer.NonGeneric.TryDeaerializeWithLengthPrefixです。

ストリームとして扱いたいアイテムがツリーのにある場合は、代替受信モデルを提供できます。偽のコレクションにIEnumerableとAdd()を実装するだけで、任意のAPI(イベントベース、たとえばSAXのような)を介してデータをプッシュできます。

また、まったく同じ方法でストリーミングデータをシリアル化できます。どの時点でも完全なオブジェクトモデルを持つ必要はありません。

より完全な例が必要な場合は、お知らせください。

+0

このMarcのおかげで – krisdyson

関連する問題