首页 > 代码库 > C#中几种序列化的比较

C#中几种序列化的比较

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);
View Code

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);
View Code

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);
View Code

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);
View Code

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);
View Code

我连续,测了N次,只贴上3次的结果吧:

看这个结果,Protobuf-net 无论序列化速度,还是序列化的体积都完胜其他几种。

此测试只是个人无聊而为,如果有不合理的地方,请大家指出来。

C#中几种序列化的比较