当前位置:编程学习 > asp >>

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

答案:     · 甘冀平·
  简介
  
    性能是一个很重要的特征。你需要事先设计好性能指标,否则日后就要为此重新编写程序。就是说:要设想好怎样最佳化地执行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”的经典性能处理技术:直到需要时,再去计算。例子如下:
  
  <%
  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 = d
  End Function
  %>
  
  对于不同的数据,可以编写类似的函数代码。
  
    数据应该按什么格式保存?任何变量类型都可以,因为所有的脚本变量都是不同的。比如说,可以保存为字符串、整型或者数据。通常,将ADO记录集的内容存储到这些变量类型中一个。为了从ADO记录集中取出数据,需要手工地拷贝数据到VBScript变量中,每次一个字段。使用任意一个ADO记录集的函数functions GetRows(),GetString() 或者 Save() (ADO 2.5)都非常得快速而且简单,这里有个函数,描述了如何使用GetRows()返回记录集数据的数组:
  
  ' Get Recordset, return as an Array
  Function 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 = Nothing
  End Function
  
  上述代码的一个更深的技巧是为列表缓存了HTML。下面是个简单的例子:
  
  ' Get Recordset, return as HTML Option list
  Function FetchEmploymentStatusList
   Dim rs, fldName, s
   Set rs = CreateObject("ADODB.Recordset")
   rs.Open "select StatusName, StatusID from EmployeeStatus", _
   "dsn=employees;uid=sa;pwd=;"
   s = "<select name=""EmploymentStatus">" & vbCrLf
   Set fldName = rs.Fields("StatusName") ' ADO Field Binding
   Do Until rs.EOF
   ' Next line violates Don't Do String Concats,
   ' but it's OK because we are building a cache
   s = s & " <option>" & fldName & "</option>" & vbCrLf
   rs.MoveNext
   Loop
   s = s & "</select>" & vbCrLf
   rs.Close
   Set rs = Nothing ' See Release Early
   FetchEmploymentStatusList = s ' Return data as a String
  End Function
  
  在合适的环境下,可以在Application或者Session中缓存ADO记录集本身,但是有2点提示:
  
  ADO必须是自由线程标记的
  需要使用disconnected recordset方式
    如果不能保证上述2个条件,就不要缓存ADO记录集,因为这会产生很大的危险性。
  
    当在Application或Session中保存数据后,数据将一直保持,除非程序改变它、Session变量到期或者Web应用程序重新启动。如果数据需要更新,怎么办?可以调用只有管理员才能访问的ASP页面来更新数据,或者,通过函数周期性的自动更新数据。下面的例子中,与缓存数据一起保存了时钟标记,过一段时间后,就刷新数据。
  
  <%
  ' error handing not shown...
  Const UPDATE_INTERVAL = 300 ' Refresh interval, in seconds
  
  ' Function to return the employment status list
  Function GetEmploymentStatusList
   UpdateEmploymentStatus
   GetEmploymentStatusList = Application("EmploymentStatusList")
  End Function
  
  ' Periodically update the cached data
  Sub UpdateEmploymentStatusList
   Dim d, strLastUpdate
   strLastUpdate = Application("LastUpdate")
   If (strLastUpdate = "") Or _
   (UPDATE_INTERVAL < 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 If
  End Sub
  
  有另外一个例子,请参阅 World’s Fastest ListBox with Application Data。
  
    必须意识到,在Session或者Application对象中缓存大容量的数组不是一个好的方法。存取数组中任何元素前,脚本语言的规则要求首先要建立整个数组的临时备份。比如,如果在Application对象中缓存一个100,000个元素的数组,其中包含U.S.邮政编码与本地气象站的对应关系,ASP就必须首先拷贝所有100,000个气象站信息到临时数组中,然后才能选择其中一个字符串进行处理。在这种情况下,创建一个定制的组件,编写一个方法存储气象站信息,是非常好的方法。
  
  

上一个:如何增强ASP程序性能(3)
下一个:ASP发送E-MAIL

CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,