protobuf-net 与 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#中几种序列化的比较

protobuf-net 与 C#中几种序列化的比较

protobuf-net 与 C#中几种序列化的比较

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

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

你可能感兴趣的:(protobuf)