Estaba haciendo una comparación entre BinaryFormatter
y serializador Protobuf-net y estaba bastante contento con lo que found, pero lo que es extraño es que Protobuf-net logró serializar los objetos en una matriz de bytes más pequeños de lo que obtendría si solo escribió el valor de cada propiedad en una matriz de bytes sin ningún metadato.¿Tiene Protobuf-net compresión incorporada para la serialización?
Sé que Protobuf-net admite la intercepción de cadenas si establece AsReference
en true
, pero no estoy haciendo eso en este caso, ¿así que Protobuf-net proporciona cierta compresión por defecto?
Aquí hay un código que puede ejecutar para ver por sí mismo:
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());
}
EDIT: se olvidó de agregar, la clase SimpleObject se ve así:
[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; }
}
gracias, ¡todo tiene sentido ahora! – theburningmonk
¿Por qué protobuf hace 1 byte solo para los 128 valores? 8 bits permite escribir 256 valores diferentes. – tobi
@tobi usa la codificación "varint" para el número de campo, lo que significa 7 bits de carga útil, y 1 bit "hay otro byte para leer". Sigues leyendo hasta que el MSB sea cero. –