把这二周做的一个 .NET 应用性能优化的实践经验分享出来,记录的同时也请大家踊跃发言,分享更多。由于业务特点、整体架构设计和外围系统等因素,这个应用的性能瓶颈主要是由于 XML 相关处理造成的,其中包括大 XML 数据(50M 以上)的解析和查询、从外围系统下载 XML 数据、B/S 结构中的并发处理快速响应要求等。通过本次实践,对 .NET Framework 提供的 XML 处理有了更加深入的研究和理解,并做了一些验证并实施。最终结果还是很理想的,主要降低服务器 CPU 利用率的目标也达到,从之前的 50% 以上 (双核机器,实际上单个核心已经饱和)降低到 10% 左右,有些业务可降到 5% 左右。
首先列下我所了解的 XML 处理方式有哪些。
在 .NET Framework 3.5 中,如果不使用其它的解析器(如 vtd-xml)的话,主要会有以下 4 种:
基于 XML Dom 的 Document 树处理方式
主要使用的方法或属性有 Load、LoadXml、OuterXMl、InnerXml、SelectNodes (XPath 查询)等。
XmlDocument doc = new XmlDocument();
doc.Load("data.xml");
XmlNodeList children = doc DocumentElement.SelectNodes("*");
XmlNodeList allauthors = doc.SelectNodes("//authors/author");
foreach (XmlNode node in allauthors)
{
// handle node.
}
基于 XML Dom 的准 SAX 处理方式
主要使用的方法或属性有 LoadXml、CreateNavigator、Select (XPath 查询)、MoveNext 等。这里之所以说是“准 SAX 方式”,是因为这里虽然具备了单向向前和只读以及标签触发的性质,但这毕竟是在使用的 Xml Dom 的前提下,也就是必须要有构造 Document 树(LoadXml 方法调用)的过程。
XmlDocument dom = new XmlDocument();
dom.Load("data.xml");
XPathNavigator nav = dom.CreateNavigator();
nav.MoveToRoot();
string xpath = @"//Rows[OneColumn = 'SomeValue']";
XPathNodeIterator ite = nav.Select(xpath, null);
while (ite.MoveNext())
{
// handle ite.Current.Value.
}
基于 XmlTextReader 的 SAX 处理方式
主要使用的方法或属性有 Read、LocalName、ReadString 等。这种方法与 SAX 处理模型一致,单向向前、标签触发、无需 Dom 树支持。
xmlReader = new XmlTextReader("data.xml");
while (xmlReader.Read())
{
switch (xmlReader.LocalName)
{
case "OneColumn":
{
// handle xmlReader.ReadString().
break;
}
case "OtherColumn":
{
// handle "OtherColumn" element.
break;
}
default:
{
break;
}
}
}
需要注意的是,在使用这种 XmlTextReader 拉模型的处理方式时,很少会使用以 XML 文件作为数据源来构造 XmlTextReader 对象的,更多方式会使用流来构造,因此也可以想到,很容易使用这种流加上单向向前推进的方式来实现 XML 数据的加载、解析加处理的并行处理,可以提高整体性能,这在后面还会提到。
基于 Linq to XML 的处理方式
这是 .NET Framework 3.5 提供的新特性,与上面 3 种方式截然不同,它使用 XDocument 作为底层数据结构支持,使用 Linq to Entity 对集合的扩展框架直接查询 XDocument 内容,可以附加条件并排顺序、分组等,并通过延迟加载、处理的方式来减少不必要的操作,提高性能。主要会使用这些方法或属性 Load、Descendants、Element().Value、Select、Where、Order 等。
private void InitData()
{
XDocument xdom = XDocument.Load("data.xml");
// Query rows by "OonColumn" value equal "SomeValue"
var data = from d in xdom.Descendants("Rows")
where d.Element("OneColumn").Value == "SomeValue"
orderby d.Element("OneColumn").Value
select d;
BuildColumnDropDownList(data, "OneColumn", this.DropDownList1);
BuildColumnDropDownList(data, "TwoColumn", this.DropDownList2);
var subData = data.Skip(this.pageIndex * 20).Take(20); // Paging.
this.Repeater1.DataSource = subData;
this.Repeater1.DataBind();
}
private void BuildColumnDropDownList(IOrderedEnumerable<XElement> data, string columnName, DropDownList dropDownList)
{
if (data == null)
throw new ArgumentNullException("data");
if (string.IsNullOrEmpty(columnName))
throw new ArgumentNullException("columnName");
if (dropDownList == null)
throw new ArgumentNullException("dropDownList");
var colData = from irx in data.Descendants(columnName)
group irx by irx.Value into g
orderby g.Key
select g.Key;
dropDownList.DataSource = colData.ToArray();
dropDownList.DataBind();
}
上面的 4 种处理方法各有利弊,选择出相对较高性能的处理方法不是绝对的,这需要考虑具体的 XML 处理特点和设计。下面列出我了解的一些会影响 XML 处理性能的关键点,欢迎讨论、补充。
- 要处理的 XML 数据量大小。可以以 1M 大小为界线。
- 如果采用构建 XML Dom 树的方式,那么 XML 源是否每次都变化。也就是说是否每次处理 XML 数据都需要通过 Load 来重新构建 Dom 树,即 Dom 树是否可以缓存。典型的如查询类业务,所查询的源是不变的,但每次都要重查,这样就可以一次加载 Dom 树并缓存。
- 程序内部存储 XML 数据的方式。是采用 Dom 树(XmlDocument 类型)还是采用 XML 字符串(String 类型),实际上采用哪种方式都可以,但关键是要统一,不能某些模块使用 XmlDocument,某些模块使用 String,原因也很简单,InnerXML 或 OuterXML、LoadXml 都不是免费的午餐,每次调用(成对)都无谓的浪费些资源。
结合上面列出的关键点,把已有的 4 种方法来一一对比。
首先是 XML 数据量的事,根据测试和验证发现,数据量大小直接影响 Dom 树的解析、构造性能(主要是 CPU、Memory 利用率和响应时间),即 Load、LoadXML 方法,可见除了第三种“基于 XmlTextReader 的 SAX 处理方式”之外,其它的 3 种处理方式都有明确的 Load 动作。验证结果表明 1M 大小的 XML 数据量基本可以定做一个分界线,如果要处理的数据量大于 1M,则应该选择基于 XMLTextReader 的 SAX 处理方式来处理数据。
但是,通过验证也发现,虽然 XmlTextReader 省略了 Dom 树解析过程,但也正因为它没有树型关系,因而造成了用 XmlTextReader 遍历 XML 的性能不如用 XmlDocument 的性能好。
因此,如果业务属于可以一次构造 Dom 树并缓存,留作后面多次使用的话(如查询场景),还是推荐使用生成 Dom 树的处理方式,第二种“基于 XML Dom 的准 SAX 处理方式”,虽然首次加载会吃力。
对于 5M 以下数据量的 XML 处理,这里验证发现最好的选择就是 Linq to XML 了
,呵呵,延迟加载的设计让 Linq 构造很快,而且在真正解析、查询、过滤时性能表现也满意。
关于大 XML 数据的并行处理。
实际上,对于基于 XMLTextReader 的 SAX 处理方式来讲,如果输入的 XML 数据源是流形式的,则 XML 加载可以与 SAX 解析并行,而且往往也的确是可以设计成这样的,因为很难想象一个 30、40M 的 XML 数据先全都加载进内存,然后再开始 XmlTextReader 的 while(reader.MoveNext) 过程,上面也说了。在我所涉及的这个应用中,这个很大的 XML 数据是通过 HTTP GET 请求从外围系统中下载过来的,这样的场景下,我们就可以使用并行的方式来处理,即边下载边解析。
using(WebClient client = new WebClient())
{
// string content = client.DownloadString(@"http://server.foo/get_xml?id=123");
// StringReader sr = new StringReader(content);
// XmlTextReader reader = new XmlTextReader(new MemoryStream(ASCIIEncoding.Default.GetBytes(content)));
WebRequest request = HttpWebRequest.Create(@"http://server.foo/get_xml?id=123");
XmlTextReader reader = new XmlTextReader(request.GetResponse().GetResponseStream());
while (xmlReader.Read())
{
// handle read.
}
}
当然了,这种并行可行性和设计还要看具体的业务场景,具体分析。如果能并行必然会很好。
最后想说的是,SQL Server 数据库也提供了 XQuary 的方式来处理 XML 数据,允许直接从关系型数据库中存储的 XML 数据直接返回 DataSource。不过以前试验过,性能不理想,SQL Server 内存涨幅较大,而且响应时间也不靠谱。这点还想请教哪位高人指点~~
OK,就到这里。欢迎讨论、分享。
作者:lzy.je
出处:http://lzy.iteye.com
本文版权归作者所有,只允许以摘要和完整全文两种形式转载,不允许对文字进行裁剪。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
// 2009.03.21 13:39 添加 ////
忘记了说,尽量始终不要使用“基于 XML Dom 的 Document 树处理方式”来处理 XML,尽量选择其它 3 种方式。尤其是在 XML 数据比较大时。
分享到:
相关推荐
XML订单自动处理系统是基于.NET框架开发的一种高效能、可扩展的应用程序,它利用XML(Extensible Markup Language)作为数据交换格式,实现了订单数据的自动化处理。XML是一种标记语言,其设计目标是传输和存储数据...
ASP.NET是由微软公司开发的一种服务器端Web应用程序框架,用于构建功能丰富的、高性能的动态网站。结合XML(eXtensible Markup Language),可以实现数据的有效存储和管理,为新闻发布系统提供了一个强大而灵活的...
通过阅读《ASP.NET 2.0 XML编程指南》,开发者可以深入理解XML在ASP.NET环境中的应用,提升网站开发的专业技能。虽然书名没有提及,但dotnet39可能是书中一个章节的索引或者一个示例代码的目录,可能包含关于.NET ...
在.NET开发环境中,ASP.NET与XML的结合应用广泛,尤其在动态数据展示和处理方面。本项目中的“.net+xml 图片切换,下载功能”是一个典型的案例,它涉及到以下几个核心知识点: 1. **ASP.NET Web应用程序**:ASP.NET...
8. **XML在配置文件中的应用**:ASP.NET应用通常使用XML格式的配置文件(如web.config),用于存储应用设置。理解如何读取和修改这些配置文件,可以帮助开发者更好地管理和配置应用程序。 9. **XML验证**:验证XML...
为了提高.NET应用的性能,开发者可以采取多种策略,包括但不限于缓存机制、异步编程、代码优化等。例如,.NET框架提供了Task Parallel Library (TPL)来帮助开发者编写高效的并发代码。 总之,基于.NET的企业级应用...
.NET应用程序皮肤设计是一种提高用户界面(UI)美观度和用户体验的有效方法。WinForm应用程序作为.NET Framework中的一个关键组件,广泛用于开发桌面应用。通过引入皮肤系统,开发者可以为应用程序提供多样的视觉...
在Asp.net中操作XML的基本步骤通常包括以下几点: 1. 加载XML:可以使用XmlDocument的Load方法或者XDocument的Load方法从文件或流中加载XML数据。 2. 查询XML:使用XPathNavigator的Select或Evaluate方法进行XPath...
书中将详细阐述如何创建XML Schema,以及如何在ASP.NET应用程序中使用它进行数据验证。 8. **XML编程接口(DOM和SAX)**:两种主要的XML解析方法——DOM(Document Object Model)和SAX(Simple API for XML),在...
在这个"ASP.NET应用程序开发"的学习资源中,我们可以深入理解并掌握以下几个关键知识点: 1. **Web Forms与MVC模式**: - Web Forms:ASP.NET Web Forms提供了一种基于控件的事件驱动模型,类似于Windows应用程序...
在【新闻文章】Asp.net简单XML新闻发布系统 v2.0_xmlnews2.0中,我们可以预见到以下几个核心功能和知识点: 1. **XML数据存储**:系统会将新闻数据存储为XML文件,每个新闻项作为一个XML元素,包含标题、作者、日期...
在VB.NET应用编程中,你需要了解以下几个关键知识点: 1. **基础语法与数据类型**:VB.NET支持多种数据类型,包括整型、浮点型、字符串、布尔型等。理解这些基本数据类型及其转换至关重要。此外,掌握变量声明、...
ASP.NET应用程序可以配置在多台服务器上运行,通过负载均衡器分配流量,确保没有单点故障,并优化资源利用率。 6. **事务管理**:在分布式系统中,跨多个数据库或服务的事务一致性至关重要。ASP.NET支持分布式事务...
在JScript.NET程序开发中,有以下几个核心知识点: 1. **类型系统**:与传统的JavaScript不同,JScript.NET支持静态类型声明,这意味着变量在声明时可以指定类型,提高了代码的可读性和编译时的错误检查能力。 2. ...
1. **IIS配置**:确保IIS服务器正确配置,支持ASP.NET应用程序运行。 2. **权限设置**:为防止未授权访问,需设置好XML文件的读写权限。 3. **性能优化**:大量新闻可能导致XML文件过大,影响读写速度。可以考虑...
这篇毕业论文不仅展示了ASP.NET和XML在实际项目中的应用,还揭示了在面对异构数据时,如何通过合理的设计和编程技巧实现数据的有效融合,对于学习和研究Web应用开发具有一定的参考价值。后续的答辩PPT可能会进一步...
**ASP.NET XML异构数据融合技术在毕业答辩中的应用** ASP.NET是微软开发的一款用于构建Web应用程序的框架,它提供了一种高效、易用的方式来创建动态网站、Web服务和网络应用。XML(eXtensible Markup Language)则...
为了提高JScript的性能,需要注意以下几点: - **减少DOM操作**:频繁地修改DOM树会影响页面渲染速度。 - **优化事件处理**:合理注册和注销事件监听器,避免内存泄漏。 **4.2 JScript语言本身的优化** **4.3 DOM...
XML(eXtensible Markup Language)是一种用于标记数据的语言,广泛...在面试中,对这些知识点的深入理解和应用展示了一个开发者在XML处理方面的专业水平。了解并熟练掌握这些技术,对于.NET开发者的日常工作至关重要。
9. **性能优化**:包括缓存策略(如Output Cache,Data Cache),减少数据库查询,优化代码结构等提高ASP.NET应用性能的实践。 10. **部署与持续集成**:如何将ASP.NET应用程序部署到IIS服务器,配置发布设置,以及...