[更新#1] :ベンチマークをチェックすることに興味がある人がいれば、修正および修正した「デモ」プロジェクトをhttps://github.com/sidshetye/SerializersCompareにアップロードしました。
[更新#2]:ProtoBufsは、後続の反復でのみ桁違いにリードしていることがわかります。1回限りのシリアル化の場合、BinaryFormatterは1桁高速です。なんで?別の質問..。
BinaryFormatter、Json.NET、およびProtoBuf.NETを比較しようとしています(後者は今日NuGetから取得しました)。ProtoBufは実際のフィールドを出力せず、すべてnullと0を出力することがわかりました(以下を参照)。さらに、BinaryFormatterははるかに高速であるように見えます。私は基本的にシリアル化=>オブジェクトを逆シリアル化して比較しました
- 再生されたオブジェクトを含むオリジナル
- バイト単位のサイズ
- ミリ秒単位の時間
質問
- ProtoBufに、(デフォルトの)値だけでなく実際の値を実際に吐き出すようにするにはどうすればよいですか?
- 私はスピードのために何を間違っていますか?ProtoBufが最速のシリアライザーになるはずだったのに?
テストアプリから得た出力は次のとおりです。
Json: Objects identical
Json in UTF-8: 180 bytes, 249.7054 ms
BinaryFormatter: Objects identical
BinaryFormatter: 512 bytes, 1.7864 ms
ProtoBuf: Original and regenerated objects differ !!
====Regenerated Object====
{
"functionCall": null,
"parameters": null,
"name": null,
"employeeId": 0,
"raiseRate": 0.0,
"addressLine1": null,
"addressLine2": null
}
ProtoBuf: 256 bytes, 117.969 ms
私のテストでは、コンソールアプリケーション内で単純なエンティティ(以下を参照)を使用していました。システム:Windows 8x64、VS2012 Update 1、.NET4.5。ちなみに、[ProtoContract]
との[ProtoMember(X)]
規則を使用しても同じ結果が得られます。ドキュメントは明確ではありませんが、 DataContractは新しい「均一な」サポート規則であるようです(右?)
[Serializable]
[DataContract]
class SimpleEntity
{
[DataMember(Order = 1)]
public string functionCall {get;set;}
[DataMember(Order = 2)]
public string parameters { get; set; }
[DataMember(Order = 3)]
public string name { get; set; }
[DataMember(Order = 4)]
public int employeeId { get; set; }
[DataMember(Order = 5)]
public float raiseRate { get; set; }
[DataMember(Order = 6)]
public string addressLine1 { get; set; }
[DataMember(Order = 7)]
public string addressLine2 { get; set; }
public SimpleEntity()
{
}
public void FillDummyData()
{
functionCall = "FunctionNameHere";
parameters = "x=1,y=2,z=3";
name = "Mickey Mouse";
employeeId = 1;
raiseRate = 1.2F;
addressLine1 = "1 Disney Street";
addressLine2 = "Disneyland, CA";
}
}
ここに興味がある人のために、ProtoBufs用のAllSerializersクラスのスニペットがあります
public byte[] SerProtoBuf(object thisObj)
{
using (MemoryStream ms = new MemoryStream())
{
Serializer.Serialize(ms, thisObj);
return ms.GetBuffer();
}
}
public T DeserProtoBuf<T>(byte[] bytes)
{
using (MemoryStream ms = new MemoryStream())
{
ms.Read(bytes, 0, bytes.Count());
return Serializer.Deserialize<T>(ms);
}
}