我正在尝试使用protobuf-net序列化/反序列化一个简单的整数数组。然而,似乎.NET BinaryFormatter的性能优于protobuf-net,这不是我所期望的。这是我用来测试性能的代码:
[ProtoContract]
[Serializable]
public struct Vector3Double {
[ProtoMember(1)]
public double x;
[ProtoMember(2)]
public double y;
[ProtoMember(3)]
public double z;
}
public static void TestSerialization() {
var v3ds = new Vector3Double[512 * 512];
var ints = new int[512 * 512];
for (var i = 0; i < v3ds.Length; i++) {
v3ds[i].x = i;
v3ds[i].y = i;
v3ds[i].z = i;
}
var tmpFilePath = System.IO.Path.GetTempFileName();
System.Console.WriteLine("BinaryFormatter");
System.Console.WriteLine("---------------");
using (var fs = System.IO.File.Open(tmpFilePath, System.IO.FileMode.Create)) {
System.Console.Write("Array of Vector3Double (serialization): ");
var bf = new BinaryFormatter();
var sw = new Stopwatch();
sw.Start();
bf.Serialize(fs, v3ds);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
using (var fs = System.IO.File.Open(tmpFilePath, System.IO.FileMode.Open)) {
System.Console.Write("Array of Vector3Double (deserialization): ");
var bf = new BinaryFormatter();
var sw = new Stopwatch();
sw.Start();
var des = bf.Deserialize(fs);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
System.Console.WriteLine();
System.Console.WriteLine("ProtoBuf Serializer");
System.Console.WriteLine("-------------------");
using (var fs = System.IO.File.Open(tmpFilePath, System.IO.FileMode.Create)) {
System.Console.Write("Array of Vector3Double (serialization): ");
var sw = new Stopwatch();
sw.Start();
ProtoBuf.Serializer.Serialize(fs, v3ds);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
using (var fs = System.IO.File.Open(tmpFilePath, System.IO.FileMode.Open)) {
System.Console.Write("Array of Vector3Double (deserialization): ");
var sw = new Stopwatch();
sw.Start();
var des = ProtoBuf.Serializer.Deserialize<Vector3Double[]>(fs);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
System.Console.WriteLine("BinaryFormatter");
System.Console.WriteLine("---------------");
using (var fs = System.IO.File.Open(tmpFilePath, System.IO.FileMode.Create)) {
System.Console.Write("Array of int (serialization): ");
var bf = new BinaryFormatter();
var sw = new Stopwatch();
sw.Start();
bf.Serialize(fs, ints);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
using (var fs = System.IO.File.Open(tmpFilePath, System.IO.FileMode.Open)) {
System.Console.Write("Array of int (deserialization): ");
var bf = new BinaryFormatter();
var sw = new Stopwatch();
sw.Start();
var des = bf.Deserialize(fs);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
System.Console.WriteLine();
System.Console.WriteLine("ProtoBuf Serializer");
System.Console.WriteLine("-------------------");
using (var fs = System.IO.File.Open(tmpFilePath, System.IO.FileMode.Create)) {
System.Console.Write("Array of int (serialization): ");
var sw = new Stopwatch();
sw.Start();
ProtoBuf.Serializer.Serialize(fs, ints);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
using (var fs = System.IO.File.Open(tmpFilePath, System.IO.FileMode.Open)) {
System.Console.Write("Array of int (deserialization): ");
var sw = new Stopwatch();
sw.Start();
var des = ProtoBuf.Serializer.Deserialize<int[]>(fs);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
}
这些是我得到的时间结果(所有时间都是ms):
BinaryFormatter
---------------
Array of Vector3Double (serialization): 401
Array of Vector3Double (deserialization): 1266
ProtoBuf Serializer
-------------------
Array of Vector3Double (serialization): 206
Array of Vector3Double (deserialization): 186
BinaryFormatter
---------------
Array of int (serialization): 2
Array of int (deserialization): 1
ProtoBuf Serializer
-------------------
Array of int (serialization): 57
Array of int (deserialization): 60
因此,BinaryFormatter在大约1到2毫秒内序列化/反序列化整数数组,而protobuf-net串行器/解串器需要57到60毫秒。我在上面的代码中有什么问题吗?或者protobuf-net不适合原始数组?
更新2016/04/29
我对protobuf-net-r668源代码进行了一些调试,看起来数组一次一个项地写入输出流(在TypeModel.cs中的TrySerializeAuxiliaryType内)。是否有可能指定数组应该一次性写入输出流?或者我应该修改源代码以便为我的使用场景序列化/反序列化数组?