ASP动态生成的内容以什么方式输出效率最高?最好用哪种方法提取数据库记录集?本文测试了近20个这类ASP开发中常见的问题,测试工具所显示的时间告诉我们:这些通常可以想当然的问题不仅值得关注,而且还有出乎意料的秘密隐藏在内。

蝈蝈俊 2000-07-26 04:44:00
一、概述
作 者 : 仙人掌工作
   原文出处:http://www.asptoday.com/articles/20000113.htm

   编译如下:

   ASP开发者总是在追求更好的应用性能和可伸缩性。虽然有许多书籍和网站能够为实现这些目标提供出色的建议,然而,这些建议的根据常常是从ASP工作原理出发所作出的判断,不能对实际性能的改善程度作任何定量的分析。由于这些建议通常意味着编码过程的复杂化、降低代码的可读性,开发者不能根据ASP应用的性能改善程度评估遵从这些建议所付出的代价是否合理,无法看到实际性能的任何度量。

   本文提供一些ASP代码的性能测试和分析结果,希望能够帮助ASP开发者了解自己的编码习惯是否值得在未来的工程中继续保留,还是有必要修改已有的工程以获得更好的性能。本文分成两个部分:在第一部分中,我们考察ASP开发中的一些基本问题;在第二部分中,我们将深入ADO应用优化方面的测试。在测试中我们发现,许多测试结果不仅引人注目,而且可以说是出人意料。

   第一部分将回答以下问题:

ASP动态生成的内容以什么方式输出效率最高?
启用缓冲对性能的影响有多大?
ASP代码中注释对执行效率有何影响?
是否应该显式设置页面的默认脚本语言?
如果会话状态并非必需,是否有必要关闭它?
把代码放入过程或函数会影响性能吗?
使用包含文件是否对性能有影响?
实现错误控制意味着付出多大的开销?
设置事务上下文会降低代码效率吗?
VBScript Option Explicit对性能有何影响?
   测试所用的工具是Microsoft的Web Application Stress Tool(WAST),这是一个免费工具,位于 http://webtool.rte.microsoft.com/。在WAST中,我们利用一个简单的WAST测试脚本重复地调用下面介绍的测试ASP页面(每个都超过70000次)。响应时间以平均“直至最后字节的累计时间”为标准(Total Time to Last Byte,TTLB),它的含义是:从第一个请求到测试工具接收到服务器应答数据的最后一个字节之间的时间总和。

   测试服务器是196 MB内存的Pentium 166,客户机是256 MB内存的 Pentium 450。或许有的读者会认为这些机器的性能不高,不过这并不重要,因为我们不是在测试服务器的能力,而只是利用服务器处理一个页面所需要的时间来估量脚本执行效率。测试时两台机器上没有运行其他任务。测试用的WAST脚本以及ASP页面均附于本文后面的ZIP文件内,读者可以下载它进行同样的测试。


二、ASP动态生成的内容以什么方式输出效率最高?


   在服务器上生成动态内容是使用ASP最主要的原因之一,所以我们选择的第一个测试项目是确定把动态内容发送到应答流使用什么方法最好。基本的选择有两种(以及它们的一些变化):使用内嵌ASP标记,使用Response.Write语句。

   为测试这些不同的方法,我们创建了一个简单的ASP页面,页面先定义一些变量然后把它们插入到表格。虽然这个页面很简单,而且没有实际用途,但它足以让我们分离和测试各个问题。

   2.1 使用ASP内嵌标记

   第一个测试是使用ASP的内嵌标记< %= x % >,其中x是一个变量。这是使用最方便的方法,而且它可以让页面的HTML部分变得更容易阅读和维护。
< % OPTION EXPLICIT
Dim FirstName
Dim LastName
Dim MiddleInitial
Dim Address
Dim City
Dim State
Dim PhoneNumber
Dim FaxNumber
Dim EMail
Dim BirthDate

FirstName = "John"
MiddleInitial = "Q"
LastName = "Public"
Address = "100 Main Street"
City = "New York"
State = "NY"
PhoneNumber = "1-212-555-1234"
FaxNumber = "1-212-555-1234"
EMail = "john@public.com"
BirthDate = "1/1/1950"
% >

< HTML >
< HEAD >
< TITLE >Response Test< / TITLE >
< /HEAD >
< BODY >
< H1 >Response Test< /H1 >
< TABLE >
< tr >< td >< b >First Name:< /b >< /td >< td >< %= FirstName % >< /td >< /tr >
< tr >< td >< b >Middle Initial:< /b >< /td >< td >< %= MiddleInitial % >< /td >< /tr >
< tr >< td >< b >Last Name:< /b >< /td >< td >< %= LastName % >< /td >< /tr >
< tr >< td >< b >Address:< /b >< /td >< td >< %= Address % >< /td >< /tr >
< tr >< td >< b >City:< /b >< /td >< td >< %= City % >< /td >< /tr >
< tr >< td >< b >State:< /b >< /td >< td >< %= State % >< /td >< /tr >
< tr >< td >< b >Phone Number:< /b >< /td >< td >< %= PhoneNumber % >< /td >< /tr >
< tr >< td >< b >Fax Number:< /b >< /td >< td >< %= FaxNumber % >< /td >< /tr >
< tr >< td >< b >EMail:< /b >< /td >< td >< %= EMail % >< /td >< /tr >
< tr >< td >< b >Birth Date:< /b >< /td >< td >< %= BirthDate % >< /td >< /tr >
< /TABLE >
< /BODY >
< /HTML >
/app1/response1.asp的完整代码

最好记录 = 8.28 毫秒/页




   2.2 使用Response.Write输出每一行HTML代码

   许多优秀的文献指出,应当避免使用前面的内嵌标记方法,因为它导致一个称为“上下文切换”的操作。这个操作发生在Web服务器所处理的代码类型发生变化的时候(从纯HTML的发送到脚本处理,或反过来),这种切换需要一定的时间。许多程序员在了解了这一点之后,他们的第一个反应是将每一行HTML代码都用Response.Write函数来输出:
...
Response.Write("< html >")
Response.Write("< head >")
Response.Write(" < title >Response Test< /title >")
Response.Write("< /head >")
Response.Write("< body >")
Response.Write("< h1 >Response Test< /h1 >")
Response.Write("< table >")
Response.Write("< tr >< td >< b >First Name:< /b >< /td >< td >" & FirstName & "< /td >< /tr >")
Response.Write("< tr >< td >< b >Middle Initial:< /b >< /td >< td >" & MiddleInitial & "< /td >< /tr >")
...
/app1/response2.asp片断

最好记录 = 8.28 毫秒/页
响应时间 = 8.08 毫秒/页
差  额 = -0.20 毫秒 (减少 2.4%)




   和内嵌标记版本相比,我们所看到的性能改善非常小,简直令人惊讶。这或许是因为页面中多出了许多函数调用。不过这种方法还有一个更大的缺点,由于HTML代码嵌入到了函数内,脚本代码变得非常冗长,阅读和维护都不方便。

   2.3 使用封装函数

   Response.Write并不会在文本行的末尾加上CRLF(Carriage Return - Line Feed,回车换行),这是使用上面这种方法最令人失望的地方。尽管已经在服务器端把HTML代码作了很好的格式化,但在浏览器中看到的仍旧只有长长的一行代码。不过失望的不仅是这一个问题,人们很快就发现不存在能够自动添加CRLF的Response.WriteLn函数。一个很自然的反应就是创建Response.Write的封装函数,在每行的后面加上CRLF:
...
writeCR("< tr >< td >< b >First Name:< /b >< /td >< td >" & FirstName & "< /td >< /tr >")
...
SUB writeCR(str)
Response.Write(str & vbCRLF)
END SUB
/app1/response4.asp片断

最好记录 = 8.08 毫秒/页
响应时间 = 10.11 毫秒/页
差  额 = +2.03 毫秒 (增加 25.1%)




   结果是性能的大大下降。当然,这主要是因为这种方法使得函数的调用次数加倍,它对性能的影响非常明显。应当不惜代价地避免这种用法,CRLF导致每行的末尾多了两个字节,而这两个字节对于浏览器显示页面是没有用的。在大多数情况下,浏览器端HTML代码的格式美观只是方便了你的竞争者阅读和理解页面的设计。

   2.4 合并多个Response.Write

   如果不考虑最后一次有关封装函数的测试,下一个合理的步骤应当是将所有字符串从分开的Response.Write语句合并到一个语句,从而减少函数调用次数、提高代码运行效率。
...
Response.Write("< html >" & _
"< head >" & _
"< title >Response Test< /title >" & _
"< /head >" & _
"< body >" & _
"< h1 >Response Test< /h1 >" & _
"< table >" & _
"< tr >< td >< b >First Name:< /b >< /td >< td >" & FirstName & "< /td >< /tr >" & _
...
"< tr >< td >< b >Birth Date:< /b >< /td >< td >" & BirthDate & "< /td >< /tr >" & _
"< /table >" & _
"< /body >" & _
"< /html >")
/app1/response3.asp片断

最好记录 = 8.08 毫秒/页
响应时间 = 7.05 毫秒/页
差  额 = -1.03 毫秒 (减少 12.7%)




   这是目前为止最好的方法。

   2.5 合并多个Response.Write,且在每一行的末尾增加CRLF

   也有人非常关注他们的HTML代码在浏览器端是否美观,因此我们又在每一行HTML代码的末尾加上了一个回车,使用的是vbCRLF常量,其他的测试代码与上例一样。
...
Response.Write("< html >" & vbCRLF & _
"< head >" & vbCRLF & _
" < title >Response Test< /title >" & vbCRLF & _
"< /head >" & vbCRLF & _
...
/app1/response5.asp片断

最好记录 = 7.05 毫秒/页
响应时间 = 7.63 毫秒/页
差  额 = +0.58 毫秒 (增加 8.5%)




   结果是性能略有下降,这可能是因为增加了字符串连接操作,同时输出的文本也增加了。

   2.6 意见

   根据上述ASP输出测试的结果,我们得出如下编码规则:

避免过多地使用内嵌ASP。
把尽可能多的Response.Write语句合并成单个语句。
绝对不要为了加上CRLF而封装Response.Write。
如果要格式化HTML输出,直接在Response.Write语句后面加上CRLF。


三、启用缓冲对性能的影响有多大?


   如果启用缓冲,则在整个页面处理完毕之前服务器不会向浏览器发送页面内容。缓冲可以通过两种方式启用:通过在ASP页面内设置Response.Buffer属性,或通过服务器设置。下面分别测试这两种方法。

   3.1 通过脚本启用缓冲

   在ASP脚本的前面加入Response.Buffer=True,IIS将缓冲页面内容:
< % OPTION EXPLICIT
Response.Buffer = true
Dim FirstName
...
/app1/buffer__1.asp片断

最好记录 = 7.05 毫秒/页
响应时间 = 6.08 毫秒/页
差  额 = -0.97 毫秒 (减少 13.7%)




   效率大大提升了一步,不过下面还有更好的。

   3.2 通过配置服务器启用缓冲

   缓冲在IIS 5.0中默认是打开的,II4 4.0需要手工设置。设置方法如下:打开网站的属性对话框。在这个对话框中,选择主目录页上的配置按钮,然后在“应用程序选项”下选中“启用缓冲”。进行本次测试之前我们先删除了Response.Buffer语句。
最好记录 = 7.05 毫秒/页
响应时间 = 5.57 毫秒/页
差  额 = -1.48 毫秒 (减少 21.0%)




   这是目前为止我们所看到的最快的应答,比以前最好的记录降低了21%的应答时间。从现在开始,以下的测试将以这个结果作为基准。

   3.3 意见

   缓冲是改善性能的一种极好的方法,因此将服务器设置成默认启用缓冲是具有重要意义的。如果由于某种原因,启用缓冲导致了页面行为不正常,只需在该页面内加上Response.Buffer=False即可。启用缓冲时,在整个页面处理完毕之前用户不会看到任何内容,这是它的一个缺点。因此,对于复杂的页面,偶尔地调用Response.Flush更新浏览器内容不失为一种好的选择。

   现在我们又得到了下面这条规则:

始终通过服务器配置启用缓冲。



四、ASP代码中注释对执行效率有何影响?


   许多HTML开发者知道,加入HTML注释是一种坏习惯。这是因为:首先,注释增加了数据传输量;其次,HTML注释为其它开发者提供了有关页面组织的信息。那么,ASP页面中的注释又怎样?ASP中的注释永远不会被浏览器看到,但是它们增加了ASP引擎所解析的脚本的大小。

   在这个测试中,我们加入了20行注释,每行80个字符,总共16000个字符。
< % OPTION EXPLICIT
'-------------------------------------------------------------------------------
... 20 lines ...
'-------------------------------------------------------------------------------
Dim FirstName
...
/app2/comment_1.asp片断

基  准 = 5.57 毫秒/页
响应时间 = 5.58 毫秒/页
差  额 = +0.01 毫秒 (增加 0.1%)




   这个测试结果令人惊讶。虽然注释把文件大小增加了两倍以上,但对响应时间的影响极小。因此,我们又有了如下规则:

如果使用适度,ASP注释对性能影响极小,或者没有影响。


来自:
http://builder.chinabyte.com/builder_course1.shtm?buiid=746&parid=1&cate=
...全文
196 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tyro 2000-07-26
  • 打赏
  • 举报
回复
to:ghj1976
你使用过Web Application Stress Tool(WAST)吗?

28,390

社区成员

发帖
与我相关
我的任务
社区描述
ASP即Active Server Pages,是Microsoft公司开发的服务器端脚本环境。
社区管理员
  • ASP
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧