原始类型数组的protobuf-net序列化

时间:2016-04-28 22:19:53

标签: serialization deserialization protobuf-net

我正在尝试使用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内)。是否有可能指定数组应该一次性写入输出流?或者我应该修改源代码以便为我的使用场景序列化/反序列化数组?

0 个答案:

没有答案