zoukankan      html  css  js  c++  java
  • 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 无论序列化速度,还是序列化的体积都完胜其他几种。

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

  • 相关阅读:
    【原创】自己动手写工具----签到器[Beta 1.0]
    都2020了,还不好好学学泛型?
    ThreadLocal = 本地线程?
    从BWM生产学习工厂模式
    你还在用BeanUtils进行对象属性拷贝?
    JDK 1.8 之 Map.merge()
    Spring Boot认证:整合Jwt
    以商品超卖为例讲解Redis分布式锁
    如何从 if-else 的参数校验中解放出来?
    分布式全局唯一ID生成策略​
  • 原文地址:https://www.cnblogs.com/gaoshang212/p/4048720.html
Copyright © 2011-2022 走看看