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 無論序列化速度,還是序列化的體積都完勝其他幾種。

此測試只是個人無聊而為,如果有不合理的地方,請大家指出來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM