XmlConverter performance improvement

August 6th, 2009 by ganton | Print

Last year I wrote a post about how to serialize and desterilize objects to/from XML using standard .Net Framework classes (see this post).  Yesterday, I need to use the class but I need to improve the performance. When one creates XmlSerializer class many time is spend to configure it behind the scene. After its initialization serialization and deserialization is much faster. I’ve decided to store already configured XmlSerializer and to reuse it. This will improve the performance significantly. For this purpose I extended the XmlConverter class from my old post. XmlConverter stores in a static hash table each created XmlSerializer and then reuse it. If it is not required to store it it will not store it. Now XmlSerializer contains two new methods FromXml and ToXml that accept a parameter named ‘useStaticSerializer’ which tells the XmlConverter to store and reuse XmlSerializer or not. Below is the new code of the XmlConverter.

   1: using System; 

   2: using System.Collections.Generic; 

   3: using System.Linq; 

   4: using System.Text; 

   5: using System.IO; 

   6: using System.Xml.Serialization; 

   7: using System.Xml; 

   8:  

   9: public static class XmlConverter 

  10: {

  11:     private static Dictionary<Type, XmlSerializer> serializers = new Dictionary<Type, XmlSerializer>();

  12:  

  13:     private static XmlSerializer GetSerializer(bool useStaticSerializer, Type serializerType)

  14:     {

  15:         XmlSerializer serializer = null;

  16:         if (useStaticSerializer)

  17:         {

  18:             lock (serializers)

  19:             {

  20:                 if (!serializers.TryGetValue(serializerType, out serializer))

  21:                 {

  22:                     serializer = new XmlSerializer(serializerType);

  23:                     serializers.Add(serializerType, serializer);

  24:                 } 

  25:             }

  26:         }

  27:         else

  28:         {

  29:             serializer = new XmlSerializer(serializerType);

  30:         }

  31:         return serializer;

  32:     }

  33:  

  34:     public static string ToXml<T>(T value) where T : new() 

  35:     { 

  36:        return ToXml<T>(value, Encoding.UTF8, false); 

  37:     } 

  38:  

  39:     public static string ToXml<T>(T value, Encoding encoding) where T : new() 

  40:     { 

  41:        return ToXml<T>(value, Encoding.UTF8, false);

  42:     }

  43:  

  44:     public static string ToXml<T>(T value, Encoding encoding, bool useStaticSerializer) where T : new()

  45:     {

  46:         try

  47:         {

  48:             XmlSerializer serializer = GetSerializer(useStaticSerializer, typeof(T));

  49:             using (MemoryStream stream = new MemoryStream())

  50:             {

  51:                 using (TextWriter writer = new StreamWriter(stream, encoding))

  52:                 {

  53:                     serializer.Serialize(writer, value);

  54:                     int cnt = (int)stream.Length;

  55:                     byte[] arr = new byte[cnt];

  56:                     stream.Seek(0, SeekOrigin.Begin);

  57:                     stream.Read(arr, 0, cnt);

  58:                     return encoding.GetString(arr, 0, arr.Length).Trim();

  59:                 }

  60:             }

  61:         }

  62:         catch { }

  63:         return null;

  64:     }

  65:  

  66:     public static T FromXml<T>(string xml) where T : new() 

  67:     {            

  68:        return FromXml<T>(xml, false); 

  69:     }

  70:  

  71:     public static T FromXml<T>(string xml, bool useStaticSerializer) where T : new()

  72:     {

  73:         try

  74:         {

  75:             XmlSerializer serializer = GetSerializer(useStaticSerializer, typeof(T));

  76:             using (StringReader stream = new StringReader(xml))

  77:             {

  78:                 using (XmlTextReader reader = new XmlTextReader(stream))

  79:                 {

  80:                     return (T)serializer.Deserialize(reader);

  81:                 }

  82:             }

  83:         }

  84:         catch { }

  85:         return default(T);

  86:     }

  87:  

  88:     public static void ClearStaticSerializers()

  89:     {

  90:         lock (serializers)

  91:         {

  92:             serializers.Clear(); 

  93:         }

  94:     }

  95:  

  96: }

Leave a Reply