- 变量Foo被解析为全局对象。
- 变量bar被解析为Foo的成员。这实际就是一次COM方法调用。
- 变量blah被解析为Foo.bar的成员。这又是一次COM方法调用。
- 变量qaz被解析为foo.bar.blah的成员。没有错,这还是一次COM方法调用。
- 调用Foo.bar.blah.quaz(1)。再一次COM方法调用。懂了吗?
- 再次执行步骤1至步骤3以解析baz。系统并不知道调用qaz是否改变对象模型,因此必须再次执行
- 步骤1至3以解析baz。
- 将baz解析为Foo.bar.blah的成员。赋予属性。
- 再次执行步骤1至步骤3以解析zaq。
- 再次执行步骤1至步骤3以解析abc。正如您可看到的,效率相当差(且慢)。以VBScript写此代码的快速方法是:
Setmyobj=Foo.bar.blah’dotheresolutionofblahONCEMyobj.baz=myobj.qaz(1)IfMyobj.zaq=Myobj.abcThen’...
如果您使用VBScript5.0或更高版本,您可以使用With语句写此代码:
WithFoo.bar.blah.baz=.qaz(1)If.zaq=.abcThen’......EndWith
注意此技巧也适用于VB程序设计。技巧13:避免重新确定数组的维数应尽量避免Redim数组。就性能而言,如果计算机的物理内存大小有限,最好将数组的初始维数设置为其最不利的情况-或将维数设置为其最佳的情况,然后再按需要重新确定维数。这并非意味着,如果知道您不需要内存时,就随便分配几兆字节的内存。下面的代码给您显示使用Dim和Redim不当的情形。<%DimMyArray()RedimMyArray(2)MyArray(0)=?hello?MyArray(1)=?good-bye?MyArray(2)=?farewell?...’someothercodewhereyouendupneedingmorespacehappens,then...RedimPreserveMyArray(5)MyArray(3)=?morestuff?MyArray(4)=?evenmorestuff?MyArray(5)=?yetmorestuff?%>
最好一开始就将数组的初始大小Dim正确(在本例中,是5)比Redim数组使其更大好得多。您可能浪费一些内存(如果您没有使用所有的元素),但获得的好处是速度变得更快。技巧14:使用响应缓冲您可以通过启用“响应缓冲”,将要输出的一整页缓冲起来。这样就将写到浏览器的量减到最少,从而改善总体性能。每个写操作都会产生很大的系统开销(在IIS中以及在通过网络发送的数据量方面),因此写操作越少越好。由于其启动慢且使用Nagling算法(用来减轻网络塞车情况),TCP/IP在发送一些大的数据块时比必须发送许多小的数据块时的效率高得多。有两个方法启用响应缓冲。第一种,您可以使用InternetServicesManager为整个应用程序启用响应缓冲。我们建议采用这种方法,在IIS4.0和IIS5.0中默认为新的ASP应用程序启用响应缓冲。第二种,可以在每个ASP页面的接近顶端的地方加入下面的代码行,从而启用响应缓冲:<%Response.Buffer=True%>此代码行必须在任何响应数据被写到浏览器之前执行(即,在任何HTML出现在ASP脚本之前以及在使用Response.Cookies集合设置任何Cookies之前)。一般来说,最好为整个应用程序启用响应缓冲。这样,您就不必在每个页面最上面写入上述的代码行。Response.Flush关于响应缓冲有一个常见的抱怨,就是用户感觉到ASP页面的响应速度很慢(即使整个响应时间得到改进),因为他们必须等到整个页面生成,然后他们才能看到东西。对于运行时间长的页面,您可以设置Response.Buffer=False,禁用响应缓冲。但是,一个更好的策略是利用Response.Flush方法。这种方法将ASP转换的所有HTML送到浏览器。例如,在转换1,000行的表的前100行之后,ASP可以调用Response.Flush,强制将转换的结果送到浏览器,这样可使用户在其余的行准备好之前看到头100行。这种技术可以将响应缓冲与浏览器逐渐显示数据完美地结合在一起。(注意在上面的1,000行表的举例中,许多浏览器在它们看到关闭</table>标记之前不会开始显示表。检查您的目标浏览器是否支持。为避免这种情况,将表分成多个具有较少行的表,并在每个表之后调用Response.Flush。较新版本的InternetExplorer在表完全下载之前就开始显示表,如果您指定表列宽,显示速度就会特别快,这样做可避免强制InternetExplorer通过测量每个单元格的内容宽度来计算列宽。)另一个关于响应缓冲的常见的抱怨是,当产生非常大的页面时,将占用许多服务器内存。撇开产生大页面的方法不谈,这种问题也可通过巧妙使用Response.Flush来加以解决。技巧15:批处理内嵌脚本和Response.Write语句VBScript语法<%=expression%>将“expression”的值写到ASP输出流中。如果响应缓冲未启用,那么执行其中的每一条语句,都会以许多小的数据包通过网络将数据写到浏览器中。这样速度很慢。而且穿插执行少量的脚本和HTML,将引起脚本引擎和HTML之间的切换,从而降低性能。因此,使用下面的技巧:使用Response.Write调用代替捆绑紧密的内嵌表达式。例如,在下面的示例中,在每一行的每一字段对响应流有一次写操作,每一行在VBScript和HTML之间有许多切换:<table><%ForEachfldinrs.Fields%><th><%=fld.Name%></th><%NextWhileNotrs.EOF%><tr><%ForEachfldinrs.Fields%><td><%=fld.Value%></td><%Next</tr><%rs.MoveNextWend%></table>下面的代码更有效,每一行对响应流有一次写操作。所有的代码都包含在一个VBScript块内:
<table><%Foreachfldinrs.FieldsResponse.Write(?<th>?&fld.Name&?</th>?&vbCrLf)NextWhileNotrs.EOFResponse.Write(?<tr>?)ForEachfldinrs.Fields%>Response.Write(?<td>?&fld.Value&?</td>?&vbCrLf)NextResponse.Write?</tr>?Wend%></table>
当禁用响应缓冲时,这一技巧的效果特别大。最好启用响应缓冲,然后看批处理Response.Write是否有助于提高性能。(在这一特定举例中,建立表主体的嵌套循环(WhileNotrs.EOF...)可以用仔细构建的GetString调用来替代。)技巧16:如果页面需要很长时间才能完成,那么执行前使用Response.IsClientConnected如果用户性急,他们可能会在您开始执行他们的请求之前,就会放弃ASP页面。如果他们单击刷新或移到服务器上的另一个页面,在ASP请求队列的末尾就有一个新的请求等候,在队列的中间有一个断开连接的请求。当服务器的负载很高时(因此请求队列就会很长,响应时间也会相应地变长),就会经常发生这种情况,这样只能使情况变得更糟。如果用户不再连接,执行ASP页面(特别是慢的、大的ASP页面)已没有任何意义。您可以使用Response.IsClientConnected属性检查这一情况。如果它返回False,则应调用Response.End并放弃页的其余部分。事实上,IIS5.0已将这一做法编为程序-每当ASP即将执行新请求时,它就会检查请求在队列中已等候了多长时间。如果已经在那里等候了多于3秒钟,ASP将检查客户机是否仍处于连接状态,如果没有连接,就立即终止请求。您可以在配置数据库中使用AspQueueConnectionTestTime设置将超时时间由3秒调整为其它值。如果页面要花很长时间才能执行完,也可以不时地检查Response.IsClientConnected。当启用了响应缓冲时,最好不时地执行Response.Flush,以用户知道,正在发生什么事。注意在IIS4.0上,除非先执行了Response.Write,否则Response.IsClientConnected就不能正常工作。如果启用了缓冲,您也必须执行Response.Flush。在IIS5.0上,却没有必要这样做,-Response.IsClientConnected工作正常。在任何情况下,Response.IsClientConnected都会有一些开销,因此只有在一个操作至少要花(比方说)500毫秒(如果您想维持每秒钟数十页的吞吐量,这是一个很长的时间)才使用它。经验表明,不要每次重复执行紧密循环时都调用它,如显示表的许多行时-每隔二十或五十行调用一次可能比较合适。技巧17:使用<OBJECT>标记例示对象如果要引用不在所有代码路径(特别是服务器或应用程序作用域的对象)中使用的对象,使用Global.asa中<objectrunat=serverid=objname>标记声明它们,而不使用Server.CreateObject方法。Server.CreateObject能立即创建对象。如果以后不再使用该对象,您就浪费了资源。<objectid=objname>标记声明objname,但在其方法或属性第一次使用以前,不会创建objname。这又是一个惰性计算的例子。
技巧18:对于ADO和其它组件使用TypeLib声明当使用ADO时,开发人员经常加入adovbs.txt,以访问ADO的各种常量。在要使用常量的每个页面中必须包含此文件。此常量文件相当大,给每个ASP页面的编译时间和脚本大小增加了许多系统开销。IIS5.0引入了绑定到组件类型库的功能。这可使您引用类型库一次,并将其用在每个ASP页面上。每个页面不会产生编译常量文件的开销,且组件开发人员不必建立VBScript#_include文件以在ASP上使用。要访问ADOTypeLib,将下面一条语句放在Global.asa中。