In a simple test, protoBuf v2 is much slower than BinaryFormatter, when the principal data is Dictionary<int, string>. protoBuf time is 931ms, and the stream size is 7,950,000. BinaryFormatter time is 52ms, and the stream size is 193,798. So it's a big difference.
Here's the full test code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using ProtoBuf;
namespace SerDeser
{
class Program
{
static void Main(string[] args)
{
const int HOW_MANY = 10000;
var data = new TestClass[HOW_MANY];
var d1 = new Dictionary<int, string>();
for (var i = 1; i <= 100; i++)
{
d1.Add(i, i.ToString());
}
for (var i = 0; i < HOW_MANY; i++)
{
data[i] = new TestClass() {InnerData = d1};
}
SerDeser(data, "BinaryFormatter", false);
SerDeser(data, "ProtoBuf", true);
Console.ReadLine();
}
private static void SerDeser(TestClass[] data, string label, bool useProtoBuf)
{
var timer = new Stopwatch();
IFormatter formatter = null;
using (var ms = new MemoryStream())
{
timer.Start();
if (useProtoBuf)
{
Serializer.Serialize<TestClass[]>(ms, data);
}
else
{
formatter = new BinaryFormatter();
formatter.Serialize(ms, data);
}
TestClass[] clone = null;
var serTime = timer.ElapsedMilliseconds;
timer.Reset();
timer.Start();
ms.Position = 0;
if (useProtoBuf)
{
clone = Serializer.Deserialize<TestClass[]>(ms);
}
else
{
clone = formatter.Deserialize(ms) as TestClass[];
}
timer.Stop();
Console.WriteLine(string.Format("{0}: ser {1}ms; deser {2}ms; total {3}ms; length {4}", label, serTime, timer.ElapsedMilliseconds, serTime + timer.ElapsedMilliseconds, ms.Length));
if (clone.Length != data.Length) Console.WriteLine("length error.");
if (clone[1].InnerData.Count != data[1].InnerData.Count) Console.WriteLine("Content error 1");
if (clone[1].InnerData[1] != data[1].InnerData[1]) Console.WriteLine("Content error 2");
}
}
}
[ProtoContract]
[Serializable]
public class TestClass
{
public TestClass()
{
}
[ProtoMemberAttribute(1)] public Dictionary<int, string> InnerData;
}
}
I create an array of 10,000 of these, and the InnerData property of each of them is a dictionary with 100 entries. My test serializes and deserializes the array.
For the protobuf test, I simply use Serializer.Serialize(ms) where ms is a MemoryStream. (and Serializer.DeSerialize to deserialize). I can post my test driver code if asked.
So my question is, under what conditions should I expect protoBuf to be slower than or faster than BinaryFormatter?