簡體   English   中英

XML與序列化/反序列化的二進制性能

[英]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序列化。

希望這可以幫助。

有趣......想法:

  • 這是什么版本的CF; 2.0? 3.5? 特別是,CF 3.5具有Delegate.CreateDelegate ,它允許protobuf-net比CF 2.0中的can更快地訪問屬性
  • 你在注釋字段屬性嗎? 同樣,在CF中,反射優化是有限的; 你可以在CF 3.5中獲得具有屬性的 beter性能,就像在字段中我唯一可用的選項是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM