{A}{S0}简介
在这篇文章中,我将分析的方法,您可以在其中添加节点到XmlDocument和讨论哪种方式是最快的,使用。NET 1.1框架。我们如何将节点添加到一个XmlDocument?
有四种方式,你将节点添加到一个XmlDocument:XmlDocument.InsertAfterXmlDocument.InsertBeforeXmlDocument.AppendXmlDocument.PrependChild
那么,哪种方法是最快的呢?
为了回答这个问题,我创建了一个测试程序,它使用一个XML文件的内容(11KB)在内存中创建一个XmlDocument。然后,用户可以选择他想要测试哪些方法。测量结果以纳秒。你是如何进行性能测试?
人们可以轻松地说,性能测试的最简单的方法是这样的:DateTime before = DateTime.Now;
// do the test...
DateTime res = before.Subtract(DateTime.Now);
不幸的是,这段代码忘记了,在您的系统中运行的线程。我们的性能测试应用程序是不运行的所有单独的和最重要的的,它不运行所有的时间。
因此,良好的性能测试必须考虑这些问题。
我的性能测试,使用下面的方法:有两个线程。一个线程处于睡眠状态的一段时间。我喜欢它TimerThread。虽然它睡觉,其他线程调用该方法来测试,一遍又一遍,直到第一个线程被唤醒。该方法被调用的次数,注册一个变量。TimeThread执行下面的代码:(timeThatWasSleeping * 1000000)/计数器。计数器变量保存要测试的方法被称为次。在纳秒时间TimerThread计算方法需要的时间完成。
在测试中,以减低调度干扰,我已经给ThreadPriority.Highest是使测试的线程。但是,如果你多次运行测试,你可以得到不同的值,因为这个。一些测试代码
让我们来看看一些代码,我们应?
应用程序被配置使用一些静态变量。
{C}
Main()方法是设立quot;测试threadquot;和",定时器threadquot;基于用户选择的测试。static void Main(string[] args)
{
string cmd = String.Empty;
do
{
lock(mon)
{
if(run)
Monitor.Wait(mon);// wait for the test to end.
}
Console.WriteLine("XmlDocument.AppendChild: a");
Console.WriteLine("XmlDocument.InsertAfter: b");
Console.WriteLine("XmlDocument.InsertBefore: c");
Console.WriteLine("XmlDocument.PrependChild: d");
Console.WriteLine("Quit: q");
Console.Write("Enter your choice:");
cmd = Console.ReadLine();
using (StreamReader sr = new StreamReader("news.xml"))
xmlDoc.LoadXml( sr.ReadToEnd() );
run = true;
Thread thw = null;
switch(cmd)
{
case "a":
thw = new Thread(new ThreadStart(TestXmlDocAppendChild));
break;
case "b":
thw = new Thread(new ThreadStart(TestXmlDocInsertAfter));
break;
case "c":
thw = new Thread(new ThreadStart(TestXmlDocInsertBefore));
break;
case "d":
thw = new Thread(new ThreadStart(TestXmlDocPrependChild));
break;
case "q":
return;
}
Console.WriteLine("\nTest started...");
thTimer = new Thread(new ThreadStart(ThreadTimer));
thw.Priority = System.Threading.ThreadPriority.Highest;
thw.Start();
thTimer.Start();
}
while(!cmd.Equals("q"));
}
例如,测试appendChild方法的线程试图调用该方法的最大次数。private static void TestXmlDocAppendChild()
{
while(run)
{
xmlDoc.AppendChild(xmlDoc.FirstChild);
counter++;
}
}
计时器线程执行下面的代码:
结果AppendChild - 38nsInsertAfter - 12nsInsertBefore - 13nsPrependChild - 14ns结论private static void ThreadTimer()
{
Thread.Sleep(timeMilisec);
run = false;
Console.WriteLine("Result: "+(timeMilisec*1000000)/counter + "ns\n\n");
counter = 0;
lock(mon)
Monitor.PulseAll(mon);
}
InsertAfter,InsertBefore和PrependChild方法基本上是相同的性能结果。 AppendChild是慢一点。
一个有趣的结论是AppendChild和PrependChild之间的区别。第一quot;添加到指定的子节点,这nodequot结束节点;和第二quot;这node.quot的子节点列表的开头将指定的节点,因此,它的速度更快插入节点的子节点列表的开头,而不是结束。挑战
此测试1500Mhz的英特尔奔腾M处理器和内存运行Windows XP专业版为512 MB。我想挑战大家想运行这些测试后的结果。
希望你能提高你的代码与此性能测试。历史2006年9月1日:战后初期