我在BinaryFormatter
和Protobuf-net串行器之间进行了一些比较,并且对我的found很满意,但奇怪的是Protobuf-net设法将对象序列化为比我得到的更小的字节数组将每个属性的值写入没有任何元数据的字节数组中。Protobuf-net是否具有用于序列化的内置压缩?
我知道Protobuf-net支持字符串实习,如果你设置AsReference
为true
,但我没有这样做,那么Protobuf-net默认提供了一些压缩?
下面是一些代码可以运行自己看看:
var simpleObject = new SimpleObject
{
Id = 10,
Name = "Yan",
Address = "Planet Earth",
Scores = Enumerable.Range(1, 10).ToList()
};
using (var memStream = new MemoryStream())
{
var binaryWriter = new BinaryWriter(memStream);
// 4 bytes for int
binaryWriter.Write(simpleObject.Id);
// 3 bytes + 1 more for string termination
binaryWriter.Write(simpleObject.Name);
// 12 bytes + 1 more for string termination
binaryWriter.Write(simpleObject.Address);
// 40 bytes for 10 ints
simpleObject.Scores.ForEach(binaryWriter.Write);
// 61 bytes, which is what I expect
Console.WriteLine("BinaryWriter wrote [{0}] bytes",
memStream.ToArray().Count());
}
using (var memStream = new MemoryStream())
{
ProtoBuf.Serializer.Serialize(memStream, simpleObject);
// 41 bytes!
Console.WriteLine("Protobuf serialize wrote [{0}] bytes",
memStream.ToArray().Count());
}
编辑:忘了补充,该SimpleObject类看起来是这样的:
[Serializable]
[DataContract]
public class SimpleObject
{
[DataMember(Order = 1)]
public int Id { get; set; }
[DataMember(Order = 2)]
public string Name { get; set; }
[DataMember(Order = 3)]
public string Address { get; set; }
[DataMember(Order = 4)]
public List<int> Scores { get; set; }
}
谢谢,这一切都有道理吧! – theburningmonk
为什么protobuf仅为128个值创建1个字节? 8位允许写入256个不同的值。 – tobi
@tobi它使用“varint”编码字段编号 - 这意味着7位有效负载,1位“有另一个字节要读取”。你继续阅读直到MSB为零。 –