ASP开发人员为了在他们的设计项目中获得更好的性能和可扩展性而不断努力幸运地是有许多书籍和站点在这方面提供了很好的建议但是这些建议的基础都是从ASP平台工作的结构上所得出的结论对实际获得的性能的提高没有量的测量由于这些建议需要更加复杂的编码过程并降低了编码的可读性开发人员就只能在看不到实际运行效果的情况下独自衡量为了提高他们ASP应用程序的性能是否值得付出这些代价
本文分为两大部分我将介绍一些性能测试结果帮助开发人员来确定某一特定举措是否不仅对将来的项目来说是值得的并且能够对原来的项目进行更新在第一部分我将回顾一些ASP开发的基础性问题在第二部分将涉及一些最优化ADO函数并将它们的结果与调用VB COM对象执行相同ADO函数的ASP页面进行比较这些结果很让人开眼界甚至有些时候是很令人吃惊的
在本文中我们将回答以下问题
* 将ASP生成的内容写入响应流中最有效的方法是什么?
* 是否应该开启缓沖器?
* 是否应该考虑向ASP代码中增加注释?
* 是否应该为页面明确地设置默认语言?
* 如果不需要是否应该关闭Session 状态?
* 是否应该把脚本逻辑放在子程序和函数区中?
* 使用包含文件有什么影响?
* 执行错误处理时会施加什么样的负载?
* 设置一个上下文处理是否对性能有影响?
所有测试都是用Microsoft的Web应用程序重点工具(WAST)来进行的这是一个免费的工具可以在这里()找到我用WAST创建了一个简单的test 脚本反复调用下面所描述的ASP页面测试(每个超过次)反应的时间基于平均最后字节总时间(TTLB) 也就是从最初请求的时间到工具从服务器接收最后一位数据的时间我们的测试服务器是一个Pentium 内存为MB客户机为Pentium 内存为MB你也许会想这些机器的性能并不算很高级但是不要忘了我们并不是要测试服务器的容量我们只是要测试服务器每次处理一个页面所用的时间测试期间这些机器不做其它工作WAST 测试脚本测试报告以及所有的ASP测试页面都包含在ZIP文件(/articles/images/zip)中你可以自己进行回顾和测试
将ASP生成的内容写入响应流中最有效的方法是什么?
使用ASP的一个最主要原因是在服务器上生成动态内容所以很明显我们测试的起点是确定将动态内容发送到响应流中的最适合的方式在多种选择中有两个是最基本的一是使用内联ASP标记另一个是使用ResponseWrite 语句
为测试这些选择我们创建了一个简单的ASP页面其中定义了一些变量然后将它们的值插入表格中虽然这个页面很简单也不是很实用但它允许我们分离并测试一些单独的问题
使用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 = Main Street
City = New York
State = NY
PhoneNumber =
FaxNumber =
EMail =
BirthDate = //
% >
< HTML >
< HEAD >
< TITLE >Response Test< / TITLE >
< /HEAD >
< BODY >
< H >Response Test< /H >
< 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 >
/app/responseasp的完整代码
以前的最佳(反应速度) = msec/page
在HTML的每一行使用ResponseWrite 语句
许多比较好的学习文档建议避免使用前面的那种方法其主要理由是在输出页面和处理页面施加反应时间的过程中如果web 服务器不得不在发送纯HTML和处理脚本之间进行转换就会发生一种被称为上下文转换的问题大部分程序员一听到这里他们的第一反应就是将原始的HTML的每一行都包装在ResponseWrite函数中
…
ResponseWrite(< html >)
ResponseWrite(< head >)
ResponseWrite( < title >Response Test< /title >)
ResponseWrite(< /head >)
ResponseWrite(< body >)
ResponseWrite(< h >Response Test< /h >)
ResponseWrite(< table >)
ResponseWrite(< tr >< td >< b >First Name:< /b >< /td >< td > & FirstName & < /td >< /
tr >)
ResponseWrite(< tr >< td >< b >Middle Initial:< /b >< /td >< td > & MiddleInitial & <
/td >< /tr >)
…
/app/responseasp的片段
以前的最佳(反应速度) = msec/page
反应时间 = msec/page
差= msec (减少 %)
我们可以看到使用这种方法与使用内联标记的方法相比在性能上获得的收益非常小这也许是因为页面给服务器装载了一大堆小的函数调用这种方法最大的缺点是由于现在HTML都嵌入脚本中所以脚本代码变得更加冗长更加难以阅读和维护
使用包装函数
当我们试图使用ResponseWrite 语句这种方法时最令人灰心的发现可能就是ResponseWrite 函数不能在每行的结尾处放置一个CRLF 因此当你从浏览器中阅读源代码时本来布置得非常好的HTML现在成了没有结束的一行我想你的下一个发现可能会更令你恐怖在Response 对象中没有其姊妹函数Writeln 所以一个很明显的反应就是为ResponseWrite 函数创建一个包装函数以便给每一行都附加一个CRLF
…
writeCR(< tr >< td >< b >First Name:< /b >< /td >< td > & FirstName & < /td >< /tr >)
…
SUB writeCR(str)
ResponseWrite(str & vbCRLF)
END SUB
/app/responseasp的片段
以前的最佳(反应速度)= msec/page
反应时间= msec/page
差 = + msec (增加 %)
当然由于这种方法有效地使函数调用次数加倍其对性能的影响也很明显因此要不惜一切代价避免具有讽刺意味的是CRLF也向反应流中为每行增加了个字节而这是浏览器不需要呈现到页面上的格式化良好的HTML所做的一切就是让你的竞争者更容易阅读你的HTML源代码并理解你的设计
将连续的ResponseWrite 连接到一个单独语句中
不考虑我们前面用包装函数进行的测试下一个合乎逻辑的步骤就是从单独的ResponseWrite 语句中提取出所有的字符串将它们连接到一个单独语句中这样就减少了函数调用的次数极大地提高了页面的性能
…
ResponseWrite(< html > & _
< head > & _
< title >Response Test< /title > & _
< /head > & _
< body > & _
< h >Response Test< /h > & _
< 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 >)
/app/responseasp的片段
以前的最佳(反应速度)= msec/page