前一段时间写了一个用xml作为数据储存方式的站点,感觉速度很慢。经过测试发现,原来大量的时间用来处理在网络上的dtd文件了。进而又对xml数据读取的性能进行了进一步的测试。
测试分为3种类型,分别是读取单条数据、读取前n条数据、读取n到m条数据的测试。这些都是网站最基本的取数据的方式。对5种类型的数据进行测试,分别为
dtd在网络上的xml(本机web服务器)、dtd在文件系统中的xml、不包含dtd的xml、sql server 2000、access。
测试数据
xml的数据结构如以下dtd所描述:
<?xml version="1.0" encoding="gb2312" ?>
<!--产品-->
<!ELEMENT product ( class, intro, image, price, content ) >
<!--
id 产品唯一标志
name 产品名称
-->
<!ATTLIST product id ID #REQUIRED
name CDATA #REQUIRED >
<!--产品类别-->
<!ELEMENT class ( #PCDATA ) >
<!--介绍-->
<!ELEMENT intro ( #PCDATA ) >
<!--产品图片-->
<!ELEMENT image ( #PCDATA ) >
<!--产品单价-->
<!ELEMENT price ( #PCDATA ) >
<!--产品详细介绍-->
<!ELEMENT content ( #PCDATA ) >
测试使用DOM模型读取xml,当读取多条记录时先列出所有xml文件,然后再选择一部分构造DOM对象,代码如下:
XmlDocument [] docs = new XmlDocument[ loop ];
string [] files = Directory.GetFiles( @"D:/Temp/XmlLoadTester/TestData/public" );
int end = start + num;
for( int j = start; j < end; j ++ )
{
XmlDocument xml = new XmlDocument();
xml.Load( files[j] );
docs[j] = xml;
}
每一组测试数据都包含77个xml文件。
sql server与access使用的数据表为sql
server自带的nothwind数据库中的products表(其中access中的表结构及数据均为sql
server导出)。分别使用SqlClient和OleDb进行数据库连接,使用DataApater将数据填充到DataTable中。取出n条数据
的时候使用的是sql语句中的top n,取出n到m条记录的时候使用的是如下sql语句:
"select top " + (m-n) + "
* from products where productid not in ( select top " + n + " productid
from products order by productid ) order by productid"
数据表中有77条记录。
测试环境
硬件:amd Sempron 2800+(超频到1.9GHZ),onda N61G,512M ddr 400,7200prm 40g pata
软件:windows 2003 server, sql server 2000, iis6.0, .net framework 1.1
测试结果
下表是这次测试的结果(单位:秒):
|
连续读取一条记录1000次
|
读取15条记录100次
|
读取15条记录1000次
|
读取40条1000次
|
读取30条到45条记录1000次
|
读取60条到75条记录1000次
|
dtd在网络中的xml
|
11.734
|
22.015
|
193.515
|
469.984
|
179.406
|
同左
|
dtd在文件系统中的xml
|
4.125
|
7.968
|
79
|
187.968
|
74.437
|
同左
|
不包含dtd的xml
|
0.953
|
3.125
|
31.312
|
52
|
29.609
|
同左
|
SqlServer
|
1.187
|
0.125
|
1.406
|
1.781
|
1.312
|
1.359
|
Accesss
|
37.250
|
3.781
|
37..406
|
48.265
|
51.125
|
1:03.328
|
从测试结果来看,处理dtd会对性能产生严重影响。不过不包含dtd的xml的性能明显已经超过access。使用xml在中小型站点上替代access是完全可行的。
测试中的一些问题
1.cpu占用率:读取xml的时候cpu占用率一直为100%。sql server的cpu占用率也很高,不过很快数据读取就结束了。access是cpu占用率最低的,最复杂的操作也不会达到30%。如果从cpu效率来说的话,xml恐怕是最低的了。
2.dtd缓存:在读取dtd在网络中的xml时,cpu占用率一直不稳定,如下图所示:
我觉得可能是.net对dtd有缓存,过一段时间后缓存就失效了,然后再到网络上取一次dtd。
3.获取文件列表的问题:因为担心数据条数多的时候列出文件列表会另性能降低,所以额外对列出文件作了测试,测试代码如下:
for( int i = 0; i < 1000; i++ )
{
string [] files = Directory.GetFiles( dir );
}
奇怪的是当dir是包含xml数据的文件夹时(含77个文件),这段代码运行了19秒,而列出c:/window/system32目录下的文件时
(2500+个文件)时,只用了12秒多一点。难道是windows对这个文件夹作优化了,还是别的原因?我又将xml数据复制到一个新建文件夹中,复制
了837份,结果列出这个文件夹的文件也只用了12.9秒。难道文件越多列出的时间用的越少?不过至少证明了在文件很多的情况下用xml的性能也不会降低
很多。