8

コンテキスト:これは、質問に答える前に削除された質問に基づいていますが、良い質問だと思うので、整理して言い換えて、再投稿しました。

多くの割り当てが問題となるprotobuf-netを使用した高スループットのシナリオ(特にGCの場合)では、オブジェクトを再利用できますか?たとえば、Clear()メソッドを追加することによって?

[ProtoContract]
public class MyDTO
{
    [ProtoMember(1)]
    public int Foo { get; set; }
    [ProtoMember(2)]
    public string Bar { get; set; }
    [ProtoMember(3, DataFormat = DataFormat.Group)]
    public List<int> Values { get { return values; } }
    private readonly List<int> values = new List<int>();

    public void Clear()
    {
        values.Clear();
        Foo = 0;
        Bar = null;
    }
}
4

1 に答える 1

6

protobuf-netがClear()メソッド自体を呼び出すことはありませんが、単純なケースでは、これを自分で実行して、Mergeメソッドを使用できます(v1 APIで、またはDeserializev2 APIでオブジェクトを渡すだけです)。例えば:

MyDTO obj = new MyDTO();
for(...) {
    obj.Clear();
    Serializer.Merge(obj, source);        
}

これにより、毎回新しいオブジェクトを作成するのではなく、既存 のデータにデータがロードされます。obj

オブジェクト割り当ての数を減らし、オブジェクトのプーリングを処理したり、自分で再利用したりする、より複雑なシナリオでは、カスタムファクトリを使用できます。たとえば、次のMyDTOようなメソッドを追加できます。

// this can also accept serialization-context parameters if
// you want to pass your pool in, etc
public static MyDTO Create()
{
    // try to get from the pool; only allocate new obj if necessary
    return SomePool.GetMyDTO() ?? new MyDTO();
}

そして、app-startupで、protobuf-netを構成してそれを認識します。

RuntimeTypeModel.Default[typeof(MyDTO)].SetFactory("Create");

(-ファクトリメソッドが問題の型内で宣言されていない場合に役立ちます)SetFactoryも受け入れることができます)MethodInfo

これにより、通常の構築メカニズムの代わりにファクトリメソッドが使用されます。Clear()ただし、オブジェクトを使い終わったら、オブジェクトをクレンジング()し、プールに戻すのは完全にあなたの仕事です。ファクトリアプローチの特に優れている点は、リストなどの新しいサブアイテムに対して機能することです。これは、からだけでは実行できませんMerge

于 2012-08-15T09:30:22.227 に答える