C#中幾種序列化的比較,這次比較只是比較了 序列化的耗時和序列後文件的大小。dom
幾種序列化分別是:ide
1. XmlSerializer測試
2. BinaryFormatterui
3. DataContractSerializerthis
4. DataContractJsonSerializerspa
5. protobuf-netpwa
前四種爲.Net 自帶的類庫,最後一種爲 Google Protocol Bufferscode
首先,選作一個實體類,作爲序列化的對象,加入了一個可序列化的字典,讓實體類 稍稍的複雜一點。orm
Code:xml
[Serializable] [ProtoContract] public class User { [ProtoMember(1)] public int ID { get; set; } [ProtoMember(2)] public string Name { get; set; } [ProtoMember(3)] public int Age { get; set; } [ProtoMember(4)] public SerializableDictionary<Guid, Guid> Dictionary { get; set; } } [Serializable] public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable { public void WriteXml(XmlWriter write) // Serializer { var keySerializer = new XmlSerializer(typeof(TKey)); var valueSerializer = new XmlSerializer(typeof(TValue)); foreach (KeyValuePair<TKey, TValue> kv in this) { write.WriteStartElement("SerializableDictionary"); write.WriteStartElement("key"); keySerializer.Serialize(write, kv.Key); write.WriteEndElement(); write.WriteStartElement("value"); valueSerializer.Serialize(write, kv.Value); write.WriteEndElement(); write.WriteEndElement(); } }
public void ReadXml(XmlReader reader) // Deserializer { reader.Read(); var keySerializer = new XmlSerializer(typeof(TKey)); var valueSerializer = new XmlSerializer(typeof(TValue)); while (reader.NodeType != XmlNodeType.EndElement) { reader.ReadStartElement("SerializableDictionary"); reader.ReadStartElement("key"); TKey tk = (TKey)keySerializer.Deserialize(reader); reader.ReadEndElement(); reader.ReadStartElement("value"); TValue vl = (TValue)valueSerializer.Deserialize(reader); reader.ReadEndElement(); reader.ReadEndElement(); this.Add(tk, vl); reader.MoveToContent(); } reader.ReadEndElement(); } public XmlSchema GetSchema() { return null; } }
而後,初始化一個集合,有1000個User對象,每一個User對象中的字典,有500對Guid
var list = new List<User>(); var random = new Random(); for (int i = 0; i < 1000; i++) { var id = random.Next(0, 10000); var user = new User { ID = id, Name = "Name" + id, Age = random.Next(1, 100) }; var dic = new SerializableDictionary<Guid, Guid>(); for (int j = 0; j < 500; j++) { dic.Add(Guid.NewGuid(), Guid.NewGuid()); } user.Dictionary = dic; list.Add(user); }
最後,開始序列化,計時用 Stopwatch
1. Xml序列化
Stopwatch sw = new Stopwatch(); //XmlSerializer sw.Start(); var xmlSerializer = new XmlSerializer(typeof(List<User>)); const string xmlfile = "xml.txt"; var fi = new FileInfo(xmlfile); using (var stream = fi.Create()) { xmlSerializer.Serialize(stream, list); } sw.Stop(); fi.Refresh(); Console.WriteLine("XML Time : {0} , Size : {1}K", sw.Elapsed, fi.Length / 1024);
2. 二進制序列化
//BinarySerializer sw.Restart(); var binarySerializer = new BinaryFormatter(); const string binaryfile = "binary.txt"; var binaryfi = new FileInfo(binaryfile); using (var stream = binaryfi.Create()) { binarySerializer.Serialize(stream, list); } sw.Stop(); binaryfi.Refresh(); Console.WriteLine("Binary Time : {0} , Size : {1}K", sw.Elapsed, binaryfi.Length / 1024);
3. DataContractSerializer
//DataContractSerializer sw.Restart(); var dataContractSerializer = new DataContractSerializer(typeof(List<User>)); const string dataContractfile = "dataContract.txt"; var dataContractfi = new FileInfo(dataContractfile); using (var stream = dataContractfi.Create()) { dataContractSerializer.WriteObject(stream, list); } sw.Stop(); fi.Refresh(); Console.WriteLine("DataContrac Time : {0} , Size : {1}K", sw.Elapsed, dataContractfi.Length / 1024);
4. DataContractJsonSerializer
//DataContractJsonSerializer sw.Restart(); var dataContractJsonSerializer = new DataContractJsonSerializer(typeof(List<User>)); const string dataContractJsonfile = "dataContractJson.txt"; var dataContractJsonfi = new FileInfo(dataContractJsonfile); using (var stream = dataContractJsonfi.Create()) { dataContractJsonSerializer.WriteObject(stream, list); } sw.Stop(); fi.Refresh(); Console.WriteLine("DataContractJson Time : {0} , Size : {1}K", sw.Elapsed, dataContractJsonfi.Length / 1024);
5. protobuf-net
sw.Restart(); //protobuf-net const string protobuffile = "buffer.txt"; var pbfi = new FileInfo(protobuffile); using (var stream = pbfi.Create()) { Serializer.Serialize(stream, list); } sw.Stop(); fi.Refresh(); Console.WriteLine("Protobuf-net Time : {0} , Size : {1}K", sw.Elapsed, pbfi.Length / 1024);
我連續,測了N次,只貼上3次的結果吧:
看這個結果,Protobuf-net 不管序列化速度,仍是序列化的體積都完勝其餘幾種。
此測試只是我的無聊而爲,若是有不合理的地方,請你們指出來。