protobuf-net 與 C#中幾種序列化的比較

C#中幾種序列化的比較,這次比較只是比較了 序列化的耗時和序列後文件的大小。dom

幾種序列化分別是:ide

1. XmlSerializer測試

2. BinaryFormatterui

3. DataContractSerializerthis

4. DataContractJsonSerializerspa

5. protobuf-netpwa

前四種爲.Net 自帶的類庫,最後一種爲 Google Protocol Bufferscode

首先,選作一個實體類,作爲序列化的對象,加入了一個可序列化的字典,讓實體類 稍稍的複雜一點。orm

Code:xml

    [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 不管序列化速度,仍是序列化的體積都完勝其餘幾種。

此測試只是我的無聊而爲,若是有不合理的地方,請你們指出來。

相關文章
相關標籤/搜索