[更新#1] :如果其他人有兴趣查看基准测试,我已将修改和修复的“演示”项目上传到https://github.com/sidshetye/SerializersCompare 。
[Update#2]:我看到 ProtoBufs 仅在后续迭代中领先数量级。对于一次性序列化,BinaryFormatter 是一个快一个数量级的序列化。为什么?单独的问题...
我正在尝试比较 BinaryFormatter、Json.NET 和 ProtoBuf.NET(今天从 NuGet 获得后者)。我发现 ProtoBuf 没有输出任何真实字段,全是空值和 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 更新 1,.NET4.5。顺便说一句,我使用[ProtoContract]
and[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);
}
}