### 如何增强 ASP 程序性能(2)

技巧 6：聪明地使用 Session 对象
Session 在繁忙站点上使用时有几个缺陷。繁忙的意思是：站点上每秒有上百的页面被请求，或者同时有上千的访问用户。这个技巧对于那些要求水平扩展强的站点非常重要，也就是指这些站点：它们利用多个服务器完成数据装载或者处理大量容错。对于小型站点，比如内部网 Intranet，Session 是非常值得提倡的。
再次重申，ASP 自动地为每一个首次点击 Web 服务器的用户创建一个 Session，每一个 Session 占有大约 10KB 的内存，生存期默认是 20 分钟。
使用 Session 最大的问题不是性能，而是扩展性，Session 不能跨越多个 Web 服务器，一旦在一个服务器上创建了 Session，它的数据就驻留在那里。这意味着，如果在 Web 上使用 Session，你就得为每一个直接访问存放 Session 服务器的用户请求设计一个策略。这就是将用户“粘”在 Web 服务器上，术语“sticky sessions”就来源于此。如果 Web 服务器遇到障碍，“Stuck”用户就会丢失他们的 Session 状态，因为 Session 不保留在磁盘上。
执行粘性 session 的策略包括硬件与软件解决方式，比如 windows2000 高级服务器中的 Network Load Balancing 以及 Cisco 公司的 Local Director，但换取这些要牺牲一定的扩展性。
Application 对象也不能跨越服务器。如果需要在 Web 群中共享并更新 Application 数据，就需要使用后台数据库。然而，只读 Application 数据在 Web 群中仍然很有用。
许多对任务要求严格的站点都要设立至少 2 个 Web 服务器，所以在设计严格任务的应用程序时，就需要执行“sticky sessions”，或者简单地避免使用 Session，同时也可以采取其他保存用户状态到独立 Web 服务器的管理技术。
如果不使用 Session，一定要确认将它们关闭，这可以通过 Internet 服务管理器实现。如果决定使用 Session，可以通过几种方法来最小化它们的影响。
可以将不需要 Session 的内容（比如帮助画面，访问者区域，等等）移动到关闭 Session 的独立 ASP 应用程序中。在基础页面上，可以给 ASP 一个指示，让它不需要使用 Session。将下面的代码直接加入到 ASP 页面的头部：
<% @EnableSessionState=False %>
使用这个指示的一个很好的解释是在框架结构中 Session 创建了一个有趣的问题。ASP 确保在一个时刻只有一个来自 Session 的请求被执行，这就确保了如果浏览器为单个用户请求多个页面时，只有一个 ASP 请求在那时能够接受 Session，如此就避免了存取 Session 对象时的多线程问题。很不幸，在框架结构中的所有页面将按照连续的顺序显示出来，一个接一个，而不是同时，所以用户为了看到整个框架必须要等很长时间。规则是：如果一定的框架页面没有使用 Session，就一定要告诉 ASP 直接使用@EnableSessionState=False。
除了使用 Session 对象，还有许多其他管理会话状态的选择。对于小数量的状态（小于 4KB），我们通常建议使用 cookie、查询字符串变量以及表单隐藏域。对于象购物车一样的大数量数据，后台数据库是最合适的选择。
技巧 7：将代码装入 COM 对象中
如果要编写很多 VBScript 或者 JScript，为了提个性能，可以将代码编写成 COM 对象并且编译使用。编译代码基本上比解释性代码运行快许多，编译组件对象可通过“early binding”存取其他 COM 对象，这比在脚本中调用组件要有效。
这么做有许多优点：
COM 对象有益于从商业规则中独立出表达式规则
COM 对象使代码重用变为可能
许多开发者发现用 VB，C＋＋或者 Visual J＋＋编写程序，比 ASP 更容易调试
COM 对象也有缺点，包括初始开发时间和对不同编程技巧的需要。注意将少量 ASP 代码做成 COM 对象组件不会有好处，反而可能导致性能的损失，从而失去了编译代码的优势。怎样组合使用 ASP 脚本和 COM 对象达到最佳性能是一个测试的问题。我们注意到微软公司已经大规模在 Windows 2000/IIS 5.0 上提高了脚本与 ADO 的性能，由此，随着 IIS5.0 版本的引进，减少了编译代码的性能优势。
技巧 8：使用 Option Explicit
要在 ASP 文件中使用 Option Explicit 定义，并且放置到 ASP 文件的头部，从而强迫开发者在使用前声明所有的变量。许多程序员都认为这在应用程序调试时非常有用，因为它避免了产生错误类型变量以及偶然创建新变量的可能。
也许更重要的是，声明的变量要大大快于非声明变量。
技巧 9：拷贝经常使用的数据到脚本变量中
在 ASP 中存取 COM 对象时，应该拷贝经常使用的对象数据到脚本变量中，这样就减少了对 COM 对象的方法调用。这些调用要比存取脚本变量相对来说费时费力。当存取 Collection 和 Dictionary 对象时，使用这项技巧也减少了昂贵的查找操作。
通常，如果要不止一次地存取对象数据，就应将数据放入脚本变量中，对象数据主要也就是 Request 变量（表单和查询字符串变量）。比如，站点要传递一个叫做 UserID 的查询字符串变量，假设它将在一个特殊页面被引用 12 次，那么不需要调用 Request（“UserID”）12 次，只要在 ASP 页面的头部分配给 UserID 一个变量，然后在页面中使用它，这样做就节省了 11 次 COM 方法的调用。
实际中，存取 COM 属性或方法是很昂贵的，下面的例子展示了通用代码：
Foo.bar.blah.baz = Foo.bar.blah.qaz(1)
If Foo.bar.blah.zaq = Foo.bar.blah.abc Then ' ...
上面的代码执行后，发生以下事情：
1、变量 Foo 被当作全局对象
2、变量 bar 被当作 Foo 的一员
3、变量 blah 被当作 Foo.bar 的一员
4、变量 qaz 被当作 Foo.bar.blah 的一员
5、调用 Foo.bar.blah.quaz(1)
6、再执行步骤 1 到 3 分解 baz
7、分解 baz 做为 Foo.bar.blah 的一员
8、再执行步骤 1 到 3 分解 zaq
9、再执行步骤 1 到 3 一次分解 abc
如上所示，这非常没有效率并且很慢。更快的方法是用 VBScript 编写代码，如下：
Set myobj = Foo.bar.blah ' do the resolution of blah ONCE
Myobj.baz = myobj.qaz(1)
If Myobj.zaq = Myobj.abc Then '...
如果使用 VBScript 5.0 或者更高版本，可以用 With 语句编写：
With Foo.bar.blah
.baz = .qaz(1)
If .zaq = .abc Then '...
...
End With
注意：这个技巧也可以应用在 VB 编程中。
技巧 10：避免再定义数组
争取不要再定义数组。考虑到性能问题，如果机器的物理内存大小不够，最好按最差情况或者最佳情况设置数组的初始尺寸，需要时再重新定义。
下面的代码展示了 Dim 和 Redim 的使用：
< %
Dim MyArray()
Redim MyArray(2)
MyArray(0) = "hello"
MyArray(1) = "good-bye"
MyArray(2) = "farewell"
...
' some other code where you end up needing more space happens, then ...
Redim Preserve MyArray(5)
MyArray(3) = "more stuff"
MyArray(4) = "even more stuff"
MyArray(5) = "yet more stuff"
% >
简单地定义数组初始尺寸为合适的大小是非常好的，而不要用 Redim 加大数组。这么做也许浪费了一些内存（如果没有完全地使用空间），但是赢得了速度。