.NET 性能优化技巧与诀窍






1.60/5 (16投票s)
2006年2月28日
8分钟阅读

71191
.NET 性能优化技巧与诀窍
引言
.NET 应用程序性能优化技巧与诀窍
必须修改 Web.Config 和 Machine.config 文件
-------------------------------------------------------------
1. 将编译中的 debug 设为 false,如下所示:-
<compilation defaultLanguage="c#" debug="false">
创建应用程序时,此属性默认设置为 "true",这在开发时非常有用。 但是,部署应用程序时,请务必将其设置为 "false"
将其设置为 "true" 需要将 pdb 信息插入文件中,这会导致文件相对较大,因此处理速度会变慢。
2. 除非需要,否则关闭跟踪。
跟踪是一个很棒的功能,可以让我们跟踪应用程序的轨迹和序列。但是, 同样,它只对开发人员有用,除非您需要监控跟踪日志,否则可以将其设置为 "false"。
在部署应用程序之前,请禁用跟踪和调试。跟踪和调试可能会导致性能问题。 不建议在应用程序在生产环境中运行时进行跟踪和调试。您可以使用以下语法在 Machine.config 和 Web.config 中禁用跟踪和调试。
您可以如下关闭跟踪:-
<configuration>
<system.web>
<trace enabled="false" pageOutput="false" />
<trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true"/>
<compilation debug="false" />
</system.web>
</configuration>
3. 如果不需要,请关闭会话状态。
ASP.NET 自动管理会话状态。但是,如果您不需要会话,禁用它将有助于提高性能。
当您的页面是静态的或您不需要存储页面中捕获的信息时,您可能不需要会话状态。
您可以如下关闭会话状态:-
<sessionstate timeout="20" cookieless="false" mode="Off" stateconnectionstring="tcpip=127.0.0.1:42424"
sqlconnectionstring="data source=127.0.0.1;Trusted_Connection=no">
在页面级别进行操作
<%@ Page EnableSessionState="false" %>
构建 .NET 应用程序时必须进行更改
----------------------------------------
4. 在最终构建应用程序之前选择 Release 模式。此选项位于顶部框架中的 Window 菜单选项下方。 默认情况下,模式为 Debug
当您在 Debug 模式下构建/重新构建应用程序时,会发生几件事情。首先,它会在您的 BIN 目录下创建一个额外的 PDB 文件。这会保存所有调试信息。
其次,超时非常高,因为您在调试时需要更高的超时频率,以便您的进程一直挂起,直到您到达出现错误的精确断点。
因此,选择 Release 模式将在部署时大大提高应用程序的性能。
提高 Web 应用程序性能的一般方法
-------------------------------------------------------------
5. 在不需要时禁用 ViewState。
6. 避免频繁往返数据库。
对数据库的调用在响应时间和资源方面可能非常昂贵,可以通过使用批处理来避免。
尽可能减少对数据库的调用,并使其持续时间更短。在适用时使用 DataAdapter 非常有用, 因为它在需要时自动打开和关闭连接,并且不需要用户显式打开连接。
打开但未充分关闭的连接数量会直接影响性能下降。
7. 避免抛出异常。这非常昂贵。
8. 使用缓存来提高应用程序的性能。
9. 使用适当的身份验证机制。
您选择的身份验证机制决定了与之相关的成本,因此请选择适当的机制。一个非正式但有用的顺序如下:-
身份验证模式
1. 无
2. Windows
3. 表单
4. Passport
10. 验证从用户接收的所有输入。
尽可能使用客户端验证。但是,也要在服务器端进行检查,以避免臭名昭著的
Javascript 禁用场景。
11. 使用 Finally 方法来释放资源。
在您的 Try..Catch.. 块中,始终使用 Finally 方法来关闭打开的连接、打开的 DataReaders、文件和 其他资源,以便无论代码是在 Try 中工作还是进入 Catch,它们都会被执行。
12. String 和 StringBuilder 的用法。
如果您最初创建一个字符串,例如 s = "Hello"。然后您将其附加为 s = s + " World";您实际上是在内存中创建了两个字符串实例。 原始字符串和新字符串都将存储在内存中。 因此,您对字符串执行的所有活动都作为单独的引用存储在内存中,应尽可能避免这种情况。
使用 StringBuilder 在这类场景中非常有用。对于上面的示例,使用 StringBuilder 作为
s.Append(" World");它只将值存储在原始字符串中,并且不会创建额外的引用。
例如
字符串操作
--------------
string str="";
DateTime startTime = DateTime.Now;
Response.Write(("<br>开始时间:" + startTime.ToString()));
int i;
for(i=0;i<20000;i++)
{
str += i.ToString()+ "<br>";
}
DateTime EndTime= DateTime.Now;
Response.Write(("<br>结束时间:" + EndTime.ToString()));
输出
开始时间:3/22/2006 10:23:44 AM
结束时间:3/22/2006 10:25:08 AM
上述代码花费了 1 分 24 秒才完成操作
StringBuilder 操作
---------------------
StringBuilder strbuilder = new StringBuilder();
DateTime startTime1 = DateTime.Now;
Response.Write(("<br>开始时间:" + startTime1.ToString()));
int i1;
for (i1 = 0; i1 < 20000; i1++)
{
strbuilder.Append(i1 + "<br>");
}
DateTime EndTime1 = DateTime.Now;
Response.Write(("<br>结束时间:" + EndTime1.ToString()));
输出
开始时间:3/22/2006 10:25:08 AM
结束时间:3/22/2006 10:25:09 AM
上述代码花费了 1 秒钟才完成操作
13. 避免递归函数/嵌套循环
14. 为您的页面启用 Option Strict 和 Option Explicit。
15. 在 Visual Basic 或 JScript 代码中使用早期绑定。
16. 使用 Response.Write 进行字符串连接
在您的页面或用户控件中使用 HttpResponse.Write 方法进行字符串连接。
此方法提供非常高效的缓冲和连接服务。如果您正在执行
大量的连接,但是,以下示例中的技术,使用多次调用
Response.Write,比使用单个 Response.Write 方法连接字符串更快。
Response.Write("a");
Response.Write(myString);
Response.Write("b");
Response.Write(myObj.ToString());
Response.Write("c");
Response.Write(myString2);
Response.Write("d");
17. 避免不必要的服务器往返
使用 Page.IsPostback 避免在往返中进行额外的工作。
• 尽可能实现 Ajax UI。目的是避免整页刷新,只更新需要更改的页面部分。我认为 Scott 的文章提供了关于如何实现 Ajax Atlas 和 <atlas:updatepanel> 控件的详细信息。
• 使用客户端脚本。客户端验证有助于减少处理用户请求所需的往返次数。在 ASP.NET 中,您还可以使用客户端控件来验证用户输入。
• 使用 Page.ISPostBack 属性来确保您只在页面首次加载时执行页面初始化逻辑,而不是响应客户端回发。
If Not IsPostBack Then
LoadJScripts()
End If
• 在某些情况下,执行回发事件处理是不必要的。您可以使用客户端回调从服务器读取数据,而不是执行完整的往返。
18. 将 IO 缓冲区大小保持在 4KB 和 8KB 之间
对于几乎所有应用程序,4KB 到 8KB 之间的缓冲区将为您提供最大的性能。在非常特定的情况下,您可能会从更大的缓冲区(例如,加载可预测大小的大图像)中获得改进,但在 99.99% 的情况下,这只会浪费内存。所有源自 BufferedStream 的缓冲区都允许您将大小设置为任何您想要的值,但在大多数情况下,4 到 8 将为您提供最佳性能
19. 尽量减少 Format() 的使用
在可能的情况下,使用 toString() 而不是 format()。在大多数情况下,它将为您提供所需的功能,并且开销要小得多。
20. 优化赋值
使用 exp += val 而不是 exp = exp + val。由于 exp 可以任意复杂,这可能会导致大量不必要的工作。这迫使 JIT 评估 exp 的两个副本,很多时候这是不需要的。第一个语句可以比第二个语句更好地优化,因为 JIT 可以避免两次评估 exp。
21. 在函数中包含 Return 语句
22. 使用 For 循环进行字符串迭代
23. 显式释放或关闭所有资源
Try
_con.Open()
Catch ex As Exception
Throw ex
Finally
If Not _con Is Nothing Then
_con.Close()
End If
End Try
24. 预编译页面并禁用 AutoEventWireup
通过预编译页面,用户无需经历 ASP.NET 文件的批处理编译;这将提高用户体验到的性能。
此外,在 Machine.config 文件中将 AutoEventWireup 属性设置为 false 意味着页面将不会将方法名称与事件匹配并将其连接起来(例如,Page_Load)。如果页面开发人员想要使用这些事件,他们将需要覆盖基类中的方法(例如,他们需要覆盖 Page.OnLoad 以进行页面加载事件,而不是使用 Page_Load 方法)。如果您禁用 AutoEventWireup,您的页面将通过将事件连接留给页面作者而不是自动执行来获得轻微的性能提升。
数据库
--------
1. 使用最佳托管提供程序
2. 尽可能使用存储过程
3. 在可能的情况下使用 SqlDataReader 而不是 Dataset
3. 关闭您不使用的功能
如果不需要,请关闭自动事务登记。对于 SQL 托管提供程序,通过连接字符串完成
SqlConnection conn = new SqlConnection("Server=mysrv01;Integrated Security=true;Enlist=false");
在使用数据适配器填充数据集时,如果不需要,请不要获取主键信息(例如,不要将 MissingSchemaAction.Add 与 key 一起设置)
public DataSet SelectSqlSrvRows(DataSet dataset,string connection,string query){
SqlConnection conn = new SqlConnection(connection);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(query, conn);
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
adapter.Fill(dataset);
return dataset;
}
4. 保持数据集精简
只将您需要的记录放入数据集中。请记住,数据集将其所有数据存储在内存中,并且您请求的数据越多,通过网络传输所需的时间就越长。
5. 使用连接池和对象池