[英]XML vs Binary performance for Serialization/Deserialization
我正在開發一個緊湊的框架應用程序,需要提高性能。 該應用程序當前通過將對象序列化為XML並將其存儲在數據庫中而脫機工作。 使用分析工具,我可以看到這是一個相當大的開銷,減慢了應用程序。 我想如果我切換到二進制序列化,性能會增加,但因為在緊湊的框架中不支持,我看了protobuf-net。 序列化似乎更快,但反序列化要慢得多,並且應用程序比序列化更多地反序列化。
二進制序列化應該更快,如果是這樣,我可以做些什么來加快性能? 這是我如何使用XML和二進制文件的片段:
XML序列化:
public string Serialize(T obj)
{
UTF8Encoding encoding = new UTF8Encoding();
XmlSerializer serializer = new XmlSerializer(typeof(T));
MemoryStream stream = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8);
serializer.Serialize(stream, obj);
stream = (MemoryStream)writer.BaseStream;
return encoding.GetString(stream.ToArray(), 0, Convert.ToInt32(stream.Length));
}
public T Deserialize(string xml)
{
UTF8Encoding encoding = new UTF8Encoding();
XmlSerializer serializer = new XmlSerializer(typeof(T));
MemoryStream stream = new MemoryStream(encoding.GetBytes(xml));
return (T)serializer.Deserialize(stream);
}
Protobuf-net二進制序列化:
public byte[] Serialize(T obj)
{
byte[] raw;
using (MemoryStream memoryStream = new MemoryStream())
{
Serializer.Serialize(memoryStream, obj);
raw = memoryStream.ToArray();
}
return raw;
}
public T Deserialize(byte[] serializedType)
{
T obj;
using (MemoryStream memoryStream = new MemoryStream(serializedType))
{
obj = Serializer.Deserialize<T>(memoryStream);
}
return obj;
}
我要對此進行糾正,Marc Gravall指出第一次迭代有一個建模模型的開銷,所以我做了一些測試,平均需要1000次迭代的序列化和反序列化的XML和二進制。 我首先使用Compact Framework DLL的v2嘗試我的測試,然后使用v3.5 DLL。 這是我得到的,時間是以毫秒為單位:
.NET 2.0
================================ XML ====== Binary ===
Serialization 1st Iteration 3236 5508
Deserialization 1st Iteration 1501 318
Serialization Average 9.826 5.525
Deserialization Average 5.525 0.771
.NET 3.5
================================ XML ====== Binary ===
Serialization 1st Iteration 3307 5598
Deserialization 1st Iteration 1386 200
Serialization Average 10.923 5.605
Deserialization Average 5.605 0.279
您的方法的主要費用是實際生成XmlSerializer類。 創建序列化器是一個耗時的過程,您應該只為每個對象類型執行一次。 嘗試緩存序列化程序,看看是否可以提高性能。
按照這個建議,我看到我的應用程序的性能大大提高,這使我能夠繼續使用XML序列化。
希望這可以幫助。
有趣......想法:
Delegate.CreateDelegate
,它允許protobuf-net比CF 2.0中的can更快地訪問屬性 FieldInfo.SetValue
在CF中還有許多其他東西根本不存在,所以它必須在一些地方做出妥協。 對於過於復雜的模型,CF的泛型限制也存在已知問題 。 正在進行修復,但這是一個很大的變化,並且需要“一段時間”。
有關信息,常規(完整).NET比較各種格式(包括XmlSerializer
和protobuf-net)的一些指標在這里 。
您是否嘗試為類創建自定義序列化類? 而不是使用XmlSerializer,它是一個通用的序列化程序(它在運行時創建一堆類)。 這是一個工具(sgen)。 您在構建過程中運行它,它會生成一個可以在XmlSerializer中使用的自定義程序集。
如果您有Visual Studio,則可以在項目屬性的“構建”選項卡下找到該選項。
串行化對象或將它們寫入數據庫會影響性能嗎? 由於編寫它們可能會遇到某種緩慢的存儲,我認為它比序列化步驟要大得多。
請記住,Marc Gravell發布的性能測量結果正在測試超過1,000,000次迭代的性能。
你將它們存儲在什么類型的數據庫中? 對象是在內存中序列化還是直接存儲? 他們是如何被發送到數據庫的? 物體有多大? 如果更新了一個,您是將所有對象發送到數據庫,還是只發送了更改的對象? 您是否在內存中緩存任何內容,或者每次都從存儲中重新讀取?
XML處理起來很慢並且占用了大量空間。 已經有很多不同的嘗試來解決這個問題,而今天最流行的嘗試似乎只是放棄了一個gzip文件,就像Open Packaging Convention一樣 。
W3C已經證明gzip方法不是最優的,並且它們和其他各種組一直致力於更好的二進制序列化,適用於快速處理和壓縮,用於傳輸。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.