我有以下物品:
public partial class Game
{
public bool Finished { get; set; }
public Guid GameGUID { get; set; }
public long GameID { get; set; }
public bool GameSetup { get; set; }
public Nullable<int> MaximumCardsInDeck { get; set; }
public Player Player { get; set; }
public Player Player1 { get; set; }
public bool Player1Connected { get; set; }
public bool Player1EnvironmentSetup { get; set; }
public long Player1ID { get; set; }
public int Player1Won { get; set; }
public bool Player2Connected { get; set; }
public bool Player2EnvironmentSetup { get; set; }
public long Player2ID { get; set; }
public int Player2Won { get; set; }
public int Round { get; set; }
public Nullable<int> RoundsToWin { get; set; }
public bool Started { get; set; }
public string StateXML { get; set; }
public Nullable<DateTime> TimeEnded { get; set; }
public Nullable<int> TimeLimitPerTurn { get; set; }
public byte[] TimeStamp { get; set; }
public Nullable<DateTime> TimeStarted { get; set; }
}
这堂课会有一些测试数据。
我需要比较WCF服务的不同绑定形式使用的不同序列化程序的性能:
BasicHttpBinding=>SoapFormatter(文本格式化程序?)
BinaryBinding=>BinaryFormatter
XMLFrATATER
我需要做的是:
现在获取要序列化的对象的大小
系列化后的尺寸
序列化时间
反序列化时间
我已经试过一些东西了,但我有点挣扎。
也许已经有了一些简单的代码来进行这种测量。
最佳答案
好吧,我来咬……下面是一些原始的序列化器度量(emph:您可能需要考虑base-64/mtom以获得总体带宽需求,外加wcf添加的任何固定开销(包括空间和cpu),但是,结果首先:
BinaryFormatter
Length: 1314
Serialize: 6746
Deserialize: 6268
XmlSerializer
Length: 1049
Serialize: 3282
Deserialize: 5132
DataContractSerializer
Length: 911
Serialize: 1411
Deserialize: 4380
NetDataContractSerializer
Length: 1139
Serialize: 2014
Deserialize: 5645
JavaScriptSerializer
Length: 528
Serialize: 12050
Deserialize: 30558
(protobuf-net v2)
Length: 112
Serialize: 217
Deserialize: 250
(所以我断定protobuf net v2是赢家……)
在较新的计算机上用.NET 4.5和当前库版本更新的数字:
BinaryFormatter
Length: 1313
Serialize: 2786
Deserialize: 2407
XmlSerializer
Length: 1049
Serialize: 1265
Deserialize: 2165
DataContractSerializer
Length: 911
Serialize: 574
Deserialize: 2011
NetDataContractSerializer
Length: 1138
Serialize: 850
Deserialize: 2535
JavaScriptSerializer
Length: 528
Serialize: 8660
Deserialize: 8468
(protobuf-net v2)
Length: 112
Serialize: 78
Deserialize: 134
使用测试设备(通过优化编译,在命令行运行):
(注意我必须发明
Player
类和一些示例数据):using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Web.Script.Serialization;
using System.Xml.Serialization;
using ProtoBuf.Meta;
static class Program
{
static void Main()
{
var orig = new Game {
Finished = true, GameGUID = Guid.NewGuid(), GameID = 12345, GameSetup = false, MaximumCardsInDeck = 20,
Player = new Player { Name = "Fred"}, Player1 = new Player { Name = "Barney"}, Player1Connected = true,
Player1EnvironmentSetup = true, Player1ID = 12345, Player1Won = 3, Player2Connected = true, Player2EnvironmentSetup = true,
Player2ID = 23456, Player2Won = 0, Round = 4, RoundsToWin = 5, Started = true, StateXML = "not really xml",
TimeEnded = null, TimeLimitPerTurn = 500, TimeStamp = new byte[] {1,2,3,4,5,6}, TimeStarted = DateTime.Today};
const int LOOP = 50000;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
using (var ms = new MemoryStream())
{
var ser = new BinaryFormatter();
Console.WriteLine();
Console.WriteLine(ser.GetType().Name);
ser.Serialize(ms, orig);
Console.WriteLine("Length: " + ms.Length);
ms.Position = 0;
ser.Deserialize(ms);
var watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ms.Position = 0;
ms.SetLength(0);
ser.Serialize(ms, orig);
}
watch.Stop();
Console.WriteLine("Serialize: " + watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ms.Position = 0;
ser.Deserialize(ms);
}
watch.Stop();
Console.WriteLine("Deserialize: " + watch.ElapsedMilliseconds);
}
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
using (var ms = new MemoryStream())
{
var ser = new XmlSerializer(typeof(Game));
Console.WriteLine();
Console.WriteLine(ser.GetType().Name);
ser.Serialize(ms, orig);
Console.WriteLine("Length: " + ms.Length);
ms.Position = 0;
ser.Deserialize(ms);
var watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ms.Position = 0;
ms.SetLength(0);
ser.Serialize(ms, orig);
}
watch.Stop();
Console.WriteLine("Serialize: " + watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ms.Position = 0;
ser.Deserialize(ms);
}
watch.Stop();
Console.WriteLine("Deserialize: " + watch.ElapsedMilliseconds);
}
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
using (var ms = new MemoryStream())
{
var ser = new DataContractSerializer(typeof(Game));
Console.WriteLine();
Console.WriteLine(ser.GetType().Name);
ser.WriteObject(ms, orig);
Console.WriteLine("Length: " + ms.Length);
ms.Position = 0;
ser.ReadObject(ms);
var watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ms.Position = 0;
ms.SetLength(0);
ser.WriteObject(ms, orig);
}
watch.Stop();
Console.WriteLine("Serialize: " + watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ms.Position = 0;
ser.ReadObject(ms);
}
watch.Stop();
Console.WriteLine("Deserialize: " + watch.ElapsedMilliseconds);
}
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
using (var ms = new MemoryStream())
{
var ser = new NetDataContractSerializer();
Console.WriteLine();
Console.WriteLine(ser.GetType().Name);
ser.Serialize(ms, orig);
Console.WriteLine("Length: " + ms.Length);
ms.Position = 0;
ser.Deserialize(ms);
var watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ms.Position = 0;
ms.SetLength(0);
ser.Serialize(ms, orig);
}
watch.Stop();
Console.WriteLine("Serialize: " + watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ms.Position = 0;
ser.Deserialize(ms);
}
watch.Stop();
Console.WriteLine("Deserialize: " + watch.ElapsedMilliseconds);
}
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
{
var sb = new StringBuilder();
var ser = new JavaScriptSerializer();
Console.WriteLine();
Console.WriteLine(ser.GetType().Name);
ser.Serialize(orig, sb);
Console.WriteLine("Length: " + sb.Length);
ser.Deserialize(sb.ToString(), typeof(Game));
var watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
sb.Length = 0;
ser.Serialize(orig, sb);
}
watch.Stop();
string s = sb.ToString();
Console.WriteLine("Serialize: " + watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ser.Deserialize(s, typeof(Game));
}
watch.Stop();
Console.WriteLine("Deserialize: " + watch.ElapsedMilliseconds);
}
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
GC.WaitForPendingFinalizers();
using (var ms = new MemoryStream())
{
var ser = CreateProto();
Console.WriteLine();
Console.WriteLine("(protobuf-net v2)");
ser.Serialize(ms, orig);
Console.WriteLine("Length: " + ms.Length);
ms.Position = 0;
ser.Deserialize(ms, null, typeof(Game));
var watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ms.Position = 0;
ms.SetLength(0);
ser.Serialize(ms, orig);
}
watch.Stop();
Console.WriteLine("Serialize: " + watch.ElapsedMilliseconds);
watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
ms.Position = 0;
ser.Deserialize(ms, null, typeof(Game));
}
watch.Stop();
Console.WriteLine("Deserialize: " + watch.ElapsedMilliseconds);
}
Console.WriteLine();
Console.WriteLine("All done; any key to exit");
Console.ReadKey();
}
static TypeModel CreateProto()
{
var meta = TypeModel.Create();
meta.Add(typeof(Game), false).Add(Array.ConvertAll(typeof(Game).GetProperties(),prop=>prop.Name));
meta.Add(typeof(Player), false).Add(Array.ConvertAll(typeof(Player).GetProperties(),prop=>prop.Name));
return meta.Compile();
}
}
[Serializable, DataContract]
public partial class Game
{
[DataMember]
public bool Finished { get; set; }
[DataMember]
public Guid GameGUID { get; set; }
[DataMember]
public long GameID { get; set; }
[DataMember]
public bool GameSetup { get; set; }
[DataMember]
public Nullable<int> MaximumCardsInDeck { get; set; }
[DataMember]
public Player Player { get; set; }
[DataMember]
public Player Player1 { get; set; }
[DataMember]
public bool Player1Connected { get; set; }
[DataMember]
public bool Player1EnvironmentSetup { get; set; }
[DataMember]
public long Player1ID { get; set; }
[DataMember]
public int Player1Won { get; set; }
[DataMember]
public bool Player2Connected { get; set; }
[DataMember]
public bool Player2EnvironmentSetup { get; set; }
[DataMember]
public long Player2ID { get; set; }
[DataMember]
public int Player2Won { get; set; }
[DataMember]
public int Round { get; set; }
[DataMember]
public Nullable<int> RoundsToWin { get; set; }
[DataMember]
public bool Started { get; set; }
[DataMember]
public string StateXML { get; set; }
[DataMember]
public Nullable<DateTime> TimeEnded { get; set; }
[DataMember]
public Nullable<int> TimeLimitPerTurn { get; set; }
[DataMember]
public byte[] TimeStamp { get; set; }
[DataMember]
public Nullable<DateTime> TimeStarted { get; set; }
}
[Serializable, DataContract]
public class Player
{
[DataMember]
public string Name { get; set; }
}