问题
In the example below:
Would Class1 serialization take almost twice as long as Class2 serialization? Or would protobuf-net handle the byte[] in Class1 as already serialized data?
Pseudo example:
[ProtoContract]
class Class1
{
[ProtoMember(1)]
public byte[] SerializedData { get; set; }
}
[ProtoContract]
class Class2
{
[ProtoMember(1)]
public Class3 NonSerializedData { get; set; }
}
[ProtoContract]
class Class3
{
[ProtoMember(1)]
public string Address{ get; set; }
[ProtoMember(2)]
public string ZipCode{ get; set; }
[ProtoMember(2)]
public string Country{ get; set; }
}
Class3 _c3 = new Class3() { Address = "MyAddress", ZipCode = "90210", Country = "AZ" }
// Class 1 Serialization
Class1 _c1 = new C1();
_c1.SerializedData = protobuf.Serialize(_c3);
byte[] c1Bytes = protobuf.Serialize(_c1);
// Class 2 Serialization
Class2 _c2 = new Class2();
_c2.NonSerializedData = _c3;
byte[] c2Bytes = protobuf.Serialize(_c2);
回答1:
Or would protobuf-net handle the byte[] in Class1 as already serialized data?
A byte[]
is treated as raw data (and is written to the stream without any additional processing), but there are still some minor things needed to serialize Class1
- writing the header field, and general overheads. When dealing with individual objects, both approaches will be plenty quick enough that any difference is moot. In high volume, though, I have good reason to suspect that serializing Class2
would be noticeably faster - as dealing with a single serialization pipeline avoids a number of overheads
Would Class1 serialization take almost twice as long as Class2 serialization?
That would be an excellent thing to profile, but it would depend on your typical data. Only you can come up with the actual number. I would expect "slightly longer". In both of these, I am comparing "cost of serializing class3, then serializing a class1 composed of the output from that" vs "cost of serializing a class3 composed of a class1 instance"
Actually, if speed is your primary concern, I would expect the optimum approach to be:
[ProtoContract]
class Class2
{
[ProtoMember(1, DataFormat = DataFormat.Group)]
public Class3 NonSerializedData { get; set; }
}
This subtle tweak means that it can write Class3
in a non-buffered, forwards-only way (by using a terminator instead of a length-prefix). The only reason this isn't the default is that google explicitly prefer the length-prefix approach.
来源:https://stackoverflow.com/questions/10719169/protobuf-net-performance