我有以下对象:
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服务的不同形式的绑定所使用的不同序列化程序的 性能 :
我需要详细做的是:
我已经尝试过一些东西,但是我有点挣扎。也许已经有一些用于这种测量的简单代码。
好; 我要咬一下……这是一些原始的 串行器 指标(示例:您可能需要考虑使用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该类和一些示例数据):
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; } }