C#中几种序列化的比较,此次比较只是比较了 序列化的耗时和序列后文件的大小。
几种序列化分别是:
1. XmlSerializer
2. BinaryFormatter
3. DataContractSerializer
4. DataContractJsonSerializer
5. protobuf-net
前四种为.Net 自带的类库,最后一种为 Google Protocol Buffers
首先,选做一个实体类,做为序列化的对象,加入了一个可序列化的字典,让实体类 稍稍的复杂一点。
Code:
[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 无论序列化速度,还是序列化的体积都完胜其他几种。
此测试只是个人无聊而为,如果有不合理的地方,请大家指出来。
本文原创手打,转载请注明出处。 Electron 交流 QQ:160162552
标签:
C#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】