This is because you are repeating the exact same InnerData
instance every time. BinaryFormatter
always tracks references. protobuf-net can track references, but it does not do so by default, because the google specification has no notion of this.
However, I doubt that serializing the same instance lots of times is a useful test - it rarely represents real usage for either serializer.
To give a realistic test, generate a different InnerData
instance per HOW_MANY
, and also ensure that the string
s are different string instances each time (again, BinaryFormatter
will track references on string
s too).
Or alternatively, enable reference-tracking in protobuf-net. Unfortunately, you can't easily do this for string
s that are the immediate children of Dictionary<int,string>
.
Here's my change:
static void Main(string[] args)
{
const int HOW_MANY = 10000;
var data = new TestClass[HOW_MANY];
for (var i = 0; i < HOW_MANY; i++)
{
Dictionary<int, string> d1 = InventData();
data[i] = new TestClass() { InnerData = d1 };
}
SerDeser(data, "BinaryFormatter", false);
SerDeser(data, "ProtoBuf", true);
Console.ReadLine();
}
private static Dictionary<int, string> InventData()
{
var d1 = new Dictionary<int, string>();
for (var i = 1; i <= 100; i++)
{
d1.Add(i, i.ToString());
}
return d1;
}
with results (I added thousand separators for easy comparison):
BinaryFormatter: ser 3,413ms; deser 30,833ms; total 34,246ms; length 23,821,447
ProtoBuf: ser 450ms; deser 591ms; total 1,041ms; length 7,950,000
I know which I'd prefer!