E不小心

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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 无论序列化速度,还是序列化的体积都完胜其他几种。

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

本文原创手打,转载请注明出处。
posted on 2014-10-24 16:56  E不小心  阅读(7061)  评论(4编辑  收藏  举报