如何增强ASP程序性能(4)

<table>
<%
For each fld in rs.Fields
Response.Write ("<th>" & fld.Name & "</th>" & vbCrLf)
Next
While Not rs.EOF
Response.Write ("<tr>")
For Each fld in rs.Fields %>
Response.Write("<td>" & fld.Value & "</td>" & vbCrLf)
Next
Response.Write "</tr>"
Wend
%>
</table>

  当response buffering关闭时,这个技巧非常得有用。最好是打开response buffering,这样就可以看到批量的Response.Wwrite是如何提高了程序性能。

技巧13:使用< OBJECT >标记引用对象

  如果需要引用除代码路径外的对象(尤其是服务器、Application范围的对象),请在Global.asa文件中使用
< object runat=server id=objname >
标记来定义它们,而不要使用Server.CreateObject方法。使用Server.CreateObject方法可以立即创建对象,这样如果随后不使用它,就浪费了资源。使用
< object id=objname >
标记可以定义对象objname,但是直到它的属性或者方法首次使用时,objname才实际创建。

技巧14:避免在循环中串联字符串

许多人在循环中建立一个字符串,就象下面的样子:


s = "<table>" & vbCrLf
For Each fld in rs.Fields
s = s & " <th>" & fld.Name & "</th> "
Next

While Not rs.EOF
s = s & vbCrLf & " <tr>"
For Each fld in rs.Fields
s = s & " <td>" & fld.Value & "</td> "
Next
s = s & " </tr>"
rs.MoveNext
Wend

s = s & vbCrLf & "</table>" & vbCrLf
Response.Write s

  这存在几个问题。首先是重复的连接字符串消耗二次方的时间,而且,运行的时间与计算的字段数量也是平方的关系。下面的简单例子更清楚地说明这一点:


s = ""
For i = Asc("A") to Asc("Z")
s = s & Chr(i)
Next

  在第1层循环时,S的值是“A”;第2层循环时,VBScript要重新分配字符串,拷贝了2个字符(“AB”)到S中;第3层循环时,需要再重新分配并且拷贝3个字符到S中。在第N层循环时,就需要重新分配并拷贝N个字符到S中。那就是1+2+3+...+N的总和,也就是N*N1/2个拷贝。

  在上面的记录集例子中,如果有100个记录和5个字段,内部循环就要执行100*5500次,并且,完成所有拷贝和再分配任务的时间将接近500*500250000。这还是一个适当尺寸记录集的拷贝工作。

  在这个例子中,可以通过替换字符串连接为Response.Write()或者行内脚本(< % =fld.Value % >)的方法提高程序性能。如果response buffering打开(也应该打开),这将很快,因为Response.Write仅仅附加数据在缓冲区的尾部,而且不需要再分配。

  如果用JScript连接字符串,强烈建议使用+=操作符,就是说,使用s+=字符串,而不是s s字符串

技巧15:打开浏览器和代理的缓冲

  默认情况下,ASP禁止了浏览器和代理的缓冲功能。如果有一个每次都不要更新的页面,就应该打开浏览器和代理的缓冲,这将允许浏览器和代理在一段时间内使用该页面的缓冲拷贝数据。缓冲能够大大地减轻服务器的数据转载量,并提高用户的浏览性能。

哪些类别的动态页面适合被缓存呢?下面是一些例子:


天气页面,每5分钟更新一次
新闻或版本列表页面,每天更新2
  注意:使用浏览器或者代理缓存后,对Web服务器的点击次数就会减少。如果想精确地了解所有页面,或者对于邮递广告,就不适于使用浏览器和代理缓存了。

  浏览器缓存由HTTP“Expires头参数控制,它由Web服务器发送给浏览器。ASP提供了2个简单的方法发送这个头部参数。设置页面在未来一定时间内到期,可以使用Response.Expires属性。下面的例子将告诉浏览器内容在10分钟后过期:

< % Response.Expires = 10 % >

  设置Response.Expires为负数或者0,就禁止了缓存。对第2个属性Response.ExpiresAbsolute的设置,允许指定在一个特殊时间到来时内容过期。

< % Response.ExpiresAbsolute = #May 31,2001 13:30:15# % >

  除了使用Response对象来设置到期时间,还可以在HTML文件头部写< META >标记。尽管代理不会注意到这个标记,但是一些浏览器可以。

< META HTTP-EQUIV="Expires" VALUE="May 31,2001 13:30:15" >

  最后,对于HTTP代理,使用Response.CacheControl可以指示是否缓存内容。设置属性为“Public”,打开代理缓存内容的功能。

< % Response.CacheControl = "Public" % >

  默认情况下,这个属性是设置成“Private”的。注意:不要让代理缓冲那些显示给特定用户的页面,因为代理可能会将属于其他用户的页面送给当前用户。

技巧16:在任何可能时使用Server.Transfer,而不要用Response.Redirect

  Response.Redirect告诉浏览器请求另一个不同的页面,这常常用于引导用户到登录页面或者出错处理页面。由于重定向强迫了一个新页面请求,结果是浏览器必须要与Web服务器循环2次,并且Web服务器必须处理一个额外的请求。IIS5.0引进了一个新功能Server.Transfer,它执行在同一服务器上的页面传输,这将避免额外的浏览器-Web服务器的数据循环,形成良好的系统性能,对于用户也有较好的响应时间。

技巧17:避免使用服务器变量

  存取服务器变量导致Web站点建立一个特殊的请求并收集所有的服务器变量,而并不是你要求的那个变量。这类似于在文件夹中取回一个特殊的文件,要想取回一个文件,就得首先获取所在文件夹的信息。

  不要存取非法的Request对象(比如Request"Data")),对于那些不在Request.CookiesRequest.FormRequest.QueryString或者Request.ClientCertificate中的项目,隐含就指向了Request.ServerVariables变量,而这些变量要比其他集合对象慢得多。

技巧18:调整Web服务器

  有几个IIS调整参数可以提高站点性能。比如,对于IIS4.0,我们经常发现提高ASP ProcessorThreadMax参数能够产生重大的效果,特别是在那些要等待后台资源比如数据库或中间件产品的站点。在IIS5.0中,你可以发现调整ASP线程通道要比调整AspProcessorThreadMax效果更佳。

最佳的配置设定取决于应用程序代码、支持的硬件设备以及客户端的工作量。发现最佳配置的唯一方法就是测试。

相关参考资源

Optimizing ASP scripts
Developing Scalable Web Applications
Got Any Cache? by Nancy Winnick Cluts
Maximizing the Performance of Your Active Server Pages by Nancy Winnick Cluts
15 Seconds: Performance Section
Enhancing Performance in ASP - Part I by Wayne Plourde
When is Better Worse? Weighing the Technology Trade-Offs by Nancy Winnick Cluts
Speed and Optimization Resources by Charles Carroll
Tuning IIS
The Art and Science of Web Server Tuning with Internet Information Services 5.0
Leveraging ASP in IIS 5.0 by J.D. Meier
Tuning IIS 4.0 for High Volume Sites by Michael Stephenson
Tuning Internet Information Server Performance by Mike Moore