今天我的任务是改善传统ASP页面的性能。重写ASP.NET中的代码目前不是一个选项,所以我接受了挑战,以挤压我可以从页面中获得的每一盎司性能。
该页面包含基本的“SELECT bla bla FROM bla”到几个记录集中。 while循环遍历那些记录集并转储< tr>< td>字符串。在while循环中有一堆条件和诸如此类的东西。有3个子程序被调用,它们使用全局变量(不是作为参数传递的局部变量)。
所以没有什么真正令人震惊或任何事情。在我开始优化之前,循环大约需要15秒才能完成。在6秒左右的15秒中,sql查询占用了它。
在改变了一些事情后,我设法将其提高到7秒左右。
我改变的是:
我没有选择SELECT *,而只选择了我需要的列。查询平均下降到4秒。这是一个非常繁重的查询,其中包含视图内的视图。
我删除了循环中的所有上下文切换。所以我换了像<%= bla%>这样的东西到Response.Write(bla)。
3个子程序被定义为函数,但它们被用作sub(没有结果)。所以我把功能改成了潜艇。这有帮助吗?
进行更改后,我发现其中一个子程序占用了大部分时间。我今天没有足够的时间来改变子程序,但它包括:
每次调用页面时,该子程序运行1600次左右。
那里的任何人都有优化经典asp页面的经验吗?你有什么好的优化技巧吗?我正在寻找的是在do ...循环语句中改进代码。
我是一位经验丰富的ASP.NET开发人员,对ASP.NET中的性能改进有很多了解。经典ASP使用不同的“引擎”,所以我想知道是否有任何人对提高经典ASP的性能有任何见解。
谢谢!
中号
PS:是的,我知道经典的ASP使用VBScript
答案 0 :(得分:9)
GetRows这将创造您所寻求的速度。以下是我使用的some other tips。
答案 1 :(得分:4)
看到这是一个很受欢迎的问题,我决定解释我3年前所做的事情,加快了ASP脚本的速度。
原始脚本大量使用可调整大小的数组来存储键值,因此我修改了该代码以使用Scriting.Dictionary。例如:
Dim myDictionary
Set myDictionary = Createobject("Scripting.Dictionary")
myDictionary.item("key") = "value"
这比可调整大小的数组快得多。
另一个重大变化是字符串的连接。原始剧本充满了:
S = ""
S = S & "First line<br />"
S = S & "Second line<br />"
S = S & "Third line line<br />"
Response.Write(S)
我将其修改为:
Response.Write("First line<br />")
Response.Write("Second line<br />")
Response.Write("Third line<br />")
这产生了巨大的变化。字符串的串联是一个巨大的瓶颈,因为字符串被丢弃然后重新初始化。
另一种选择是:
S = "First line<br />" & _
"Second line<br />" & _
"Third line line<br />"
Response.Write(S)
这也是ASP.NET的一个很好的提示:使用StringBuilder而不是连接字符串。
另一个重要的变化是上下文切换。原始代码充满了:
<table>
<tr>
<td><%= rs("Col1") %></td>
<td><%= rs("Col2") %></td>
<td><%= rs("Col2") %></td>
</tr>
</table>
3个上下文切换占用了大量时间,所以我修改了这个:
<%
Response.Write("<table>")
Response.Write("<tr>")
Response.Write("<td>")
Response.Write(rs("Col1"))
Response.Write("</td>")
Response.Write("</tr>")
Response.Write("<tr>")
Response.Write("<td>")
Response.Write(rs("Col2"))
Response.Write("</td>")
Response.Write("</tr>")
Response.Write("<tr>")
Response.Write("<td>")
Response.Write(rs("Col3"))
Response.Write("</td>")
Response.Write("</tr>")
Response.Write("</table>")
%>
是的,代码非常冗余,但效果更好。
另一个小修改(实际上是一个肮脏的黑客攻击)是在SQL查询中使用WITH(NOLOCK):
conn.Query("SELECT * FROM MyTable WITH (NOLOCK) LEFT JOIN AnotherTable WITH (NOLOCK) ON MyTable.Id = AnotherTable.Id")
这有所不同。
最后,我不知道这有多大帮助,但有很多复制粘贴的代码我重构为干净的函数。
我希望找到这个帖子的人会发现这些提示很有用。
答案 2 :(得分:3)
每次调用页面时,该子程序运行1600次左右。
我说这几乎就是整个问题,但是如果不知道数据的详细信息会返回查询,那么子程序会做什么,为什么需要为页面完成1600次,降低它是很难建议的。
答案 3 :(得分:3)
我将MrChrister的答案标记为我的问题的答案“你有什么优化技巧吗?”。那里的提示很好,它设法加快脚本2秒。
我最终发现了使脚本变慢的原因。在while循环中,程序员正在做很多Filter(Array)。他基本上使用Filter(Array)来查找键/值对。
所以最终的解决方案是将Filter(Array)的代码更改为使用“Scripting.Dictionary”对象。它将代码加速了12倍。
感谢您的所有回复。
中号
答案 4 :(得分:0)
如果你真的认为问题出在那个1函数中,为什么不把代码放在这里,以便人们可以提出优化建议。
答案 5 :(得分:-2)
我经历过,在大多数情况下,您可以在经典ASP中使用StringBuilder时获得性能。 StringBuilder implementation中的经典ASP有一个很好的ajaxed library。它使用.net StringBuilder。这非常酷,易于使用:
<%
set output = new StringBuilder
do
output("some output")
loop
response.write(output.toString())
%>
如果你需要做一些调整,我建议使用ajaxed库。它设置很快,为您提供了很多经典ASP的工具。例如。也许你在使用AJAX时可以获得一些性能(或者至少是性能的印象)。