[更新#1]:我已经将我修改和修复的“演示”项目上传到https://github.com/sidshetye/SerializersCompare是否还有人有兴趣查看基准。
[更新#2]:我发现ProtoBufs仅在后续迭代中占据数量级领先地位。对于一次性序列化,BinaryFormatter要快一个数量级。为什么?单独的问题。。。
我试图比较BinaryFormatter和Json。NET和ProtoBuf。NET(今天从NuGet上获得了后者)。我发现ProtoBuf没有输出实数字段,都是null和0(见下文)。加上BinaryFormatter似乎要快得多。我基本上序列化了=
问题
我从测试应用程序获得的输出如下:
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。顺便说一句,我使用[协议]
和[协议成员(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";
}
}
对于那些感兴趣的人,这里是我的所有序列化程序类的片段
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);
}
}
首先,您的序列化/反序列化方法都损坏了;您过度报告了结果(GetBuffer()
,没有Llong
),并且您没有将任何内容写入流以进行反序列化。这是一个正确的实现(尽管如果您返回ArraySegment,您也可以使用
GetBuffer()
public static byte[] SerProtoBuf(object thisObj)
{
using (MemoryStream ms = new MemoryStream())
{
Serializer.NonGeneric.Serialize(ms, thisObj);
return ms.ToArray();
}
}
public static T DeserProtoBuf<T>(byte[] bytes)
{
using (MemoryStream ms = new MemoryStream(bytes))
{
return Serializer.Deserialize<T>(ms);
}
}
这就是为什么您没有得到任何数据。其次,您没有说明如何对其进行计时,所以这里有一些我根据您的代码编写的代码(其中还包括显示它正在获取所有值的代码)。结果优先:
Via BinaryFormatter:
1 Disney Street
Disneyland, CA
1
FunctionNameHere
Mickey Mouse
x=1,y=2,z=3
1.2
Via protobuf-net:
1 Disney Street
Disneyland, CA
1
FunctionNameHere
Mickey Mouse
x=1,y=2,z=3
1.2
Serialize BinaryFormatter: 112 ms, 434 bytes
Deserialize BinaryFormatter: 113 ms
Serialize protobuf-net: 14 ms, 85 bytes
Deserialize protobuf-net: 19 ms
分析:
两个序列化程序存储相同的数据;protobuf网的速度快了一个数量级,产量也小了5倍。我宣布:胜利者。
代码:
static BinaryFormatter bf = new BinaryFormatter();
public static byte[] SerBinaryFormatter(object thisObj)
{
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, thisObj);
return ms.ToArray();
}
}
public static T DeserBinaryFormatter<T>(byte[] bytes)
{
using (MemoryStream ms = new MemoryStream(bytes))
{
return (T)bf.Deserialize(ms);
}
}
static void Main()
{
SimpleEntity obj = new SimpleEntity(), clone;
obj.FillDummyData();
// test that we get non-zero bytes
var data = SerBinaryFormatter(obj);
clone = DeserBinaryFormatter<SimpleEntity>(data);
Console.WriteLine("Via BinaryFormatter:");
Console.WriteLine(clone.addressLine1);
Console.WriteLine(clone.addressLine2);
Console.WriteLine(clone.employeeId);
Console.WriteLine(clone.functionCall);
Console.WriteLine(clone.name);
Console.WriteLine(clone.parameters);
Console.WriteLine(clone.raiseRate);
Console.WriteLine();
data = SerProtoBuf(obj);
clone = DeserProtoBuf<SimpleEntity>(data);
Console.WriteLine("Via protobuf-net:");
Console.WriteLine(clone.addressLine1);
Console.WriteLine(clone.addressLine2);
Console.WriteLine(clone.employeeId);
Console.WriteLine(clone.functionCall);
Console.WriteLine(clone.name);
Console.WriteLine(clone.parameters);
Console.WriteLine(clone.raiseRate);
Console.WriteLine();
Stopwatch watch = new Stopwatch();
const int LOOP = 10000;
watch.Reset();
watch.Start();
for (int i = 0; i < LOOP; i++)
{
data = SerBinaryFormatter(obj);
}
watch.Stop();
Console.WriteLine("Serialize BinaryFormatter: {0} ms, {1} bytes", watch.ElapsedMilliseconds, data.Length);
watch.Reset();
watch.Start();
for (int i = 0; i < LOOP; i++)
{
clone = DeserBinaryFormatter<SimpleEntity>(data);
}
watch.Stop();
Console.WriteLine("Deserialize BinaryFormatter: {0} ms", watch.ElapsedMilliseconds, data.Length);
watch.Reset();
watch.Start();
for (int i = 0; i < LOOP; i++)
{
data = SerProtoBuf(obj);
}
watch.Stop();
Console.WriteLine("Serialize protobuf-net: {0} ms, {1} bytes", watch.ElapsedMilliseconds, data.Length);
watch.Reset();
watch.Start();
for (int i = 0; i < LOOP; i++)
{
clone = DeserProtoBuf<SimpleEntity>(data);
}
watch.Stop();
Console.WriteLine("Deserialize protobuf-net: {0} ms", watch.ElapsedMilliseconds, data.Length);
}
最后,<代码>[数据成员(…)]
支持并不是真正的“较新的‘统一’支持约定”-它当然不是“较新的”-我很确定它在类似提交4(可能更早)的时候就已经支持了这两种约定。这只是为了方便起见提供的选项:
并非所有目标平台都具有DataMemberAttribute
有些人喜欢将DTO层限制为内置标记
有些类型基本上不受您的控制,但可能已经有了这些标记(例如,从LINQ到SQL生成的数据)
- 此外,请注意2。x允许您在运行时定义模型,而无需添加属性(尽管属性仍然是最方便的方式)
我需要通过flink消费Kafka,不幸的是,Kafka消息是在serde中使用原型,完全不知道如何处理它,这里是来自互联网的代码,但我不能使它工作。 这不起作用,它会让NPE: 有人知道我做错了什么吗?使用twitter ProtobufSerializer是唯一值得拥有protobuf的方法吗?还是还有别的路要走?
问题内容: 我可能只是弄乱了原始文件中的内容,但似乎无法调用toByteArray函数。 使用Java,proto文件是使用protoc编译的。 我在说… 并且BaseMessage被声明为… 也许我缺少东西… BaseMessage扩展了GeneratedMessage,它继承了其中toByteArray是公共的AbstractMessageLite的 toByteArray(),所以我应该能够
问题内容: 我正在尝试将.NET DataTable序列化为JSON文件,然后将JSON文件反序列化为DataTable。我想很简单。 但是,我有一个表,3行3列,每个元素的类型都是double。如果第一行中的任何值为null,则当JSON.Net将json文件反序列化为DataTable对象时,第一行中为null的列的所有值都变为字符串。 需要明确的是,只有第一行的值为空时,才会发生这种情况。如
本文向大家介绍jQuery序列化表单成对象的简单实现,包括了jQuery序列化表单成对象的简单实现的使用技巧和注意事项,需要的朋友参考一下 在使用easyui的datagrid组件时,在查询时传递的查询参数是对象类型,为了方便,扩展了jquery中的序列化方法,调用该方法,可以将表单的所有数据序列化 具体使用: 以上这篇jQuery序列化表单成对象的简单实现就是小编分享给大家的全部内容了,希望能给
问题内容: 我正在尝试使用protobuf序列化结构。经过许多小时试图弄清楚我在做什么错,我决定测试google的示例,但效果不佳 我从Google(https://developers.google.com/protocol- buffers/docs/javatutorial )获得以下协议: 我正在尝试将其序列化: byte []序列化= john.toByteArray(); 我得到“ j
试图在Java中使用protobuf反序列化消息,并得到以下异常。 原因:com.google.protobuf.InvalidProtocolBufferException:在解析协议消息时,输入意外地在字段中间结束。这可能意味着输入被截断,或者嵌入的消息错误报告了自己的长度。在com.google.protobuf.InvalidProtocolBufferException.Truncate