how to optimize XML writing method?
I can only use the .NET 2.0 framework to create an XML document (> 1000 lines).
The information for the document is retrieved from the Windows Registry. The XML is written using 2 for loops and in these loops I call 3 the .ToString() method to convert the retrieved data.
As expected, it takes ages to create the XML document. I was wondering what can I do to optimize this.
public static void InitiateApp()
{
const string regadd = "SOFTWARE" + "\\" + "\\" + "Microsoft" + "\\" + "Windows NT" + "\\" + "CurrentVersion" + "\\Fonts";
RegistryKey regkey = Registry.LocalMachine.OpenSubKey(regadd);
XmlWriterSettings settings = new XmlWriterSettings();
settings.CloseOutput = true;
settings.Indent = true;
settings.IndentChars = "\t";
settings.NewLineChars = "\r\n";
settings.NewLineOnAttributes = true;
settings.OmitXmlDeclaration = true;
XmlWriter w = XmlWriter.Create("c:\\out.xml",settings);
foreach (FontFamily font in FontFamily.Families)
{
w.WriteStartEle开发者_如何转开发ment("FontFamily");
int keyCount = 0;
foreach (string key in regkey.GetValueNames())
{
if(regkey.GetValueNames()[keyCount].ToString().Contains(font.Name))
{
w.WriteStartElement("FontName",regkey.GetValueNames()[keyCount].ToString());
w.WriteElementString("FontFile",regkey.GetValue(key).ToString());
w.WriteEndElement();
}
keyCount++;
}
w.WriteEndElement();
}
w.Flush();
}
Move the multiple calls to GetValueNames
out of the loop and intialize a string array instead. That will make at least some small improvement.
string[] vals = regkey.GetValueNames();
XmlWriter w = XmlWriter.Create("c:\\out.xml",settings);
foreach (Xtype a in all_a)
{
w.WriteStartElement("newElement");
int keyCount = 0;
foreach (YType b in all_b)
{
if(vals[keyCount].ToString().Contains(a.name))
{
w.WriteStartElement("a_name",vals[keyCount].ToString());
w.WriteElementString("b_name",regkey.GetValue(key).ToString());
w.WriteEndElement();
}
Separate the registry access from the xml writing. Then you can measure each and see which is slow.
regkey.GetValueNames()[keyCount].ToString()
GetValueNames returns a string[], why call ToString?
foreach (string key in regkey.GetValueNames())
//...
if(regkey.GetValueNames()[keyCount].ToString().Contains(font.Name))
//...
w.WriteStartElement("FontName",regkey.GetValueNames()[keyCount].ToString());
Why call GetValueNames so much?
Maybe use linq to xml to write the document. Personally I feel like its a more straight forward method.
My guess is that the retrieval of the data from the registry is taking longer than your serialization. What you could do is use a producer consumer pattern to multithread the retrieval of keys from the registry (not sure that would help)... and then use a single consumer to write them out.
See Blocking Collection and the Producer-Consumer Problem
精彩评论