XmlConverter performance improvement
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