性能是一个很关键的特征。你需要事先设计好性能指标,不然日后就要为此重新编写程序。就是说:要设想好怎样最佳化地执行ASP程序?
本文提出了一点优化ASP应用和VBScript的技巧,许多技巧和缺陷都经过了研讨。这里列出的建议已经在http://www.microsoft.com 和其它站点上进行了测试,都工作得非常好。本文假设你具备ASP开发的基本知识,包含VBScript或JScript,ASP应用程序,ASP Session,和其它ASP内置对象(Request,Response和Server)。
通常,ASP的执行性能远远不仅仅依赖ASP代码本身!在本文的尾部列出了与性能相关的资源,它们含概了ASP和非ASP的部分,包含ActiveX Data Objects(ADO),Component Object Model(COM),数据库(Database),和Internet信息服务器(IIS)的配置。除了这些,还有一些非常不错的链接值得你一看。
技巧1:在Web服务器上缓存我们时常使用的数据
典型的情景是:ASP页面从后台存储中取回数据,然后以超文本标记语言(HTML)的形式形成结果。不管数据库的速度咋样,从内存中取回数据要比从后台存储设备中快得多。从本地硬盘读取数据通常也非常快。因此,提高性能可以通过缓存服务器上的数据来实现,甭管是将数据缓存在内存中,或本地硬盘中。
缓存是经典的“空间换时间”的折中方式。如果缓存得恰当,就可以看到明显的性能提升。为了让缓存有效,务必保证缓存数据是我们时常要重用的,而且也是计算起来繁琐的。装满陈旧数据的缓存是对内存的浪费。
不我们时常改变的数据是缓存的较好对象,因为不用随时考虑这些数据更新后的同步操作。组合框、参考表格、DHTML代码、扩展标记语言串、菜单和站点配置变量(包含数据源名字DSNS,Internet协议地址IP和Web路径)都是很好的缓存对象。注意:要缓存数据表达式而不是数据本身。如果一个ASP页面我们时常变化并且很费力去缓存(好比整个产品目录),就要考虑预发生HTML,而不是每次发生请求时再描述它。
技巧2:在Application或Session对象中缓存我们时常使用的数据
ASP中的Application和Session对象是在内存中缓存数据的便利容器。你可以将数据赋值给Application和Session对象,这些数据在HTTP调用期间将一直维持在内存中。Session中的数据是? 一个用户服务的,Application中的数据是所有用户共享的。
何时需要在Application和Session中装入数据?通常,当应用程序启动或会话开始时,数据就被装入了。为了在这时装入数据,在Application OnStart()或Session OnStart()中分别添加适当的代码。这些函数位于文件Global.asa中,如果原来不存在,就添加上。也可以在数据第壹次期望的时候调入,在ASP页面中添加代码,检查数据是否存在,如果没有发现,就调入它。这里有一个例子,它代表了被称为“lazy evalution”的经典性能处理技术:直到需要时,再去计算。例子如下:
$#@60;%Function GetEmploymentStatusList Dim d d = Application("EmploymentStatusList") If d = "" Then FetchEmploymentStatusList function (not shown) fetches data from DB, returns an Array d = FetchEmploymentStatusList() Application("EmploymentStatusList") = d End If GetEmploymentStatusList = dEnd Function%$#@62;对于不一样的数据,可以编写类似的函数代码。
Get Recordset, return as an ArrayFunction FetchEmploymentStatusList Dim rs Set rs = CreateObject("ADODB.Recordset") rs.Open "select StatusName, StatusID from EmployeeStatus", _ "dsn=employees;uid=sa;pwd=;" FetchEmploymentStatusList = rs.GetRows() " Return data as an Array rs.Close Set rs = NothingEnd Function上述代码的一个更深的技巧是为列表缓存了HTML。下面是个容易的案例:
Get Recordset, return as HTML Option listFunction FetchEmploymentStatusList Dim rs, fldName, s Set rs = CreateObject("ADODB.Recordset") rs.Open "select StatusName, StatusID from EmployeeStatus", _ "dsn=employees;uid=sa;pwd=;" s = "$#@60;select name=""EmploymentStatus"$#@62;" & vbCrLf Set fldName = rs.Fields("StatusName") ADO Field Binding Do Until rs.EOF Next line violates Dont Do String Concats, but its OK because we are building a cache s = s & " $#@60;option$#@62;" & fldName & "$#@60;/option$#@62;" & vbCrLf rs.MoveNext Loop s = s & "$#@60;/select$#@62;" & vbCrLf rs.Close Set rs = Nothing See Release Early FetchEmploymentStatusList = s Return data as a StringEnd Function在适当的环境下,可以在Application或Session中缓存ADO记录集本身,可是有2点提示:
$#@60;% error handing not shown...Const UPDATE_INTERVAL = 300 Refresh interval, in seconds Function to return the employment status listFunction GetEmploymentStatusList UpdateEmploymentStatus GetEmploymentStatusList = Application("EmploymentStatusList")End Function Periodically update the cached dataSub UpdateEmploymentStatusList Dim d, strLastUpdate strLastUpdate = Application("LastUpdate") If (strLastUpdate = "") Or _ (UPDATE_INTERVAL $#@60; DateDiff("s", strLastUpdate, Now)) Then Note: two or more calls might get in here. This is okay and will simply result in a few unnecessary fetches (there is a workaround for this) FetchEmploymentStatusList function (not shown) fetches data from DB, returns an Array d = FetchEmploymentStatusList() Update the Application object. Use Application.Lock() to ensure consistent data Application.Lock Application("EmploymentStatusList") = d Application("LastUpdate") = CStr(Now) Application.Unlock End IfEnd Sub有另外一个例子,请参阅 World’s Fastest ListBox with Application Data。
Set rs = Server.CreateObject("ADODB.RecordSet") rs.CursorLocation = adUseClient step 1 Populate the recordset with data rs.Open strQuery, strProv Now disconnect the recordset from the data provider and data source rs.ActiveConnection = Nothing step 2更多的关于连接池的信息请访问 ADO and SQL Server。