.NET程序优化

一、数据库操作

1、 用完马上关闭数据库连接

  访问数据库资源需要创建连接、打开连接和关闭连接几个操作。这些过程需要多次与数据库交换信息以通过身份验证, 比较耗费服务器资

源。ASP.NET 中提供了连接池(Connection Pool)改善打开和关闭数据库对性能的影响。系统将用户的数据库连接放在连接池中,需要时取出,关闭时收回连接,等待下一次的连接请求。

   连接池的大小是有限的,如果在连接池达到最大限度后仍要求创建连接,必然大大影响性能。因此,在建立数据库连接后只有在真正需要操作时才打开连接,使用完 毕后马上关闭,从而尽量减少数据库连接打开的时间,避免出现超出连接限制的情况。

用(推荐)
using(SqlConnection Conn=new SqlConnection(connstr)) 
{}//不必显示关闭


try{conn.Open();}
catch{} 
finally{conn.Close();}

2、尽量使用存储过程,并优化查询语句

   存储过程是存储在服务器上的一组预编译的SQL语 句,类似于DOS系统中的批处理文件。存储过程具有对数据库立即访问的功能,信息处理极为迅速。使用存储过程可以避免对命令的多次编译,在执行一次后其执 行规划就驻留在高速缓存中,以后需要时只需直接调用缓存中的二进制代码即可。在 .NET Framework 提供的所有数据访问方法中,基于 SQL Server的数据访问是生成高性能、可缩放 Web 应用程序的推荐选择。使用托管 SQL Server 提供程序时,可通过使用编译的存储过程而不是特殊查询获得额外的性能提高。

  另 外,存储过程在服务器端运行,独立于ASP.NET程序,便于修改,最重要的是它可以减少数据库操作语句在网络中的传输。

  优化查询语句

   ASP.Net中ADO连接消耗的资源相当大,SQL语句运行的时间越长,占用系统资源的时间也越长。因此,尽量使用优化过的SQL语句以减少执行时 间。比如,不在查询语句中包含子查询语句,尽量只返回有用的数据、字段,充分利用索引等。

3、只读数据访问用SqlDataReader,不要使用 DataSet

  SqlDataReader 类提供了一种读取从 SQL Server 数据库检索的只进数据流的方法。如果当创建 ASP.NET 应用程序时出现允许您使用它的情况,则 SqlDataReader 类提供比 DataSet 类更高的性能。情况之所以这样,是因为 SqlDataReader 使用 SQL Server 的本机网络数据传输格式从数据库连接直接读取数据。另外,SqlDataReader 类实现 IEnumerable 接口,该接口也允许您将数据绑定到服务器控件。DataSet作为一个功能强大的、支持离线的数据库,其对性能的开销也相对较大。

Sqldataread 优点:读取数据非常快。如果对返回的数据不需做大量处理的情况下,建议使用SqlDataReader,其性能要比datset好很多。缺点:直到数据读 完才可close掉于数据库的连接。

Dataset是把数据读出,缓存在内存中。缺点:对内存的占用较高。如果对返回的数据需做大量的处 理用Dataset比较好些可以减少对数据库的连接操作。优点:只需连接一次就可close于数据库的连接。

一般情况下,读取大量数据,对 返回数据不做大量处理用SqlDataReader.对返回数据大量处理用datset比较合适.对SqlDataReader和Dataset的选择取 决于程序功能的实现。

4、数据的绑定DataBinder

一般的绑定方法<%# DataBinder.Eval(Container.DataItem, "字段名") %>

用DataBinder.eval 绑定不必关心数据来源(read或dataset)。不必关心数据的类型eval会把这个数据对象转换为一个字符串。在底层绑定做了很多工作,使用了反射 性能。正因为使用方便了,但却影响了数据性能。

来看下<%# DataBinder.Eval(Container.DataItem, "字段名") %>。当于dataset绑定时,DataItem其实式一个DataRowView(如果绑定的是一个数据读取器(dataread)它就是一个 IdataRecord。)因此直接转换成DataRowView的话,将会给性能带来很大提升。

<%# ctype(Container.DataItem,DataRowView).Row("字段名") %>

对数据的绑定建议使 用<%# ctype(Container.DataItem,DataRowView).Row("字段名") %>。使用时注意两个方面:
1.需在页面添加<%@ Import namespace="System.Data"%>. 
2.注意字段名的大小写(要特 别注意)。如果和查询的不一致,在某些情况下会导致比<%# DataBinder.Eval(Container.DataItem, "字段名") %>还要慢。如果想进一步提高速度,可采用<%# ctype(Container.DataItem,DataRowView).Row(0) %>的方法。不过其可读性不高。

以上 的是vb.net的写法。在c#中:<%# ((DataRowView)Container.DataItem)["字段名"] %>

5、 返回多个结果集

无论SqlDataReader还是datset,返回多个结果集,然后用rd.NextResult()或 ds.Tables[i]来分别处理数据,减少重复连接数据库的次数。同时尽量用比较高效的SQL代替后续复杂的DataSet二次加工。

二、 页面优化

1、不使用不必要的服 务器控件(Server Control)

ASP.net中,大量的服务器端控件方便了程序开发,但也可能带来性能的损失,因为用户每操作 一次服务器端控件,就产生一次与服务器端的往返过程。因此,非必要,应当少使用Server Control。还有许多其他情况,在这些情况中呈现或数据绑定比使用服务器控件更有效,甚至是在使用服务器控件模板时。但是,如果要以编程方式操作服务 器控件的属性、处理服务器控件事件或利用视图状态保存,则使用服务器控件是适当的。

所以,尽量选择html控件。能在客户端实现的功能就在 客户端实现(熟练掌握JavaScript),减少服务器的压力。

2、不使用不必要的ViewState

默认情况下,ASP.Net对所有的Server Control都启用了ViewState(视图状态)。但ViewState需要在客户端保存一些信息,这会造成性能的消耗。当必须使用Server Control时,可以考虑禁止ViewState。
只在必要时保存服务器控件视图状态。自动视图状态管 理是服务器控件的功能,该功能使服务器控件可以在往返过程上重新填充它们的属性值(您不需要编写任何代码)。但是,因 为服务器控件的视图状态在隐藏的窗体字段中往返于服务器,所以该功能确实会对性能产生影响。您应该知道在哪些情况下视图状态会有所帮助,在哪些情况下它影 响页的性能。例如,如果您将服务器控件绑定到每个往返过程上的数据,则将用从数据绑定操作获得的新值替换保存的视图状态。在这种情况下,禁用视图状态可以 节省处理时间。

默认情况下,为所有服务器控件启用视图状态。若要禁用视图状态,请将控件的 EnableViewState 属性设置为 false,如下面的 DataGrid 服务器控件示例所示。

<asp:datagrid EnableViewState="false" runat="server"/>
您还可以使用 @ Page 指令禁用整个页的视图状态。当您不从页回发到服务器时,这将十分有用: <%@ Page EnableViewState="false" %>

注意 @ Control 指令中也支持 EnableViewState 属性,该指令允许您控制是否为用户控件启用视图状态。
若要分析页上服务器控件使用的视图状态的数量,请(通过将 trace="true" 属性包括在 @ Page 指令中)启用该页的跟踪并查看 Control Hierarchy 表的 Viewstate 列。

3、避免到服务器的不必 要的往返过程

  虽然您很可能希望尽量多地使用 Web 窗体页框架的那些节省时间和代码的功能,但在某些情况下却不宜使用 ASP.NET 服务器控件和回发事件处理。

  通常,只有在检索或存储数据时,您才需要启动到服务器的往返过程。多数数据操作可在这些往 返过程间的客户端上进行。例如,从 HTML 窗体验证用户输入经常可在数据提交到服务器之前在客户端进行。通常,如果不需要将信息传递到服务器以将其存储在数据库中,那么您不应该编写导致往返过程的 代码。

  如果您开发自定义服务器控件,请考虑让它们为支持 ECMAScript. 的浏览器呈现客户端代码。通过以这种方式使用服务器控件,您可以显著地减少信息被不必要的发送到 Web 服务器的次数。

  使用 Page.IsPostBack 避免对往返过程执行不必要的处理

  如果您编写处理服务器控件回发处理的代码,有时可能需要在首次请求页 时执行其他代码,而不是当用户发送包含在该页中的 HTML 窗体时执行的代码。根据该页是否是响应服务器控件事件生成的,使用 Page.IsPostBack 属性有条件地执行代码。例如,下面的代码演示如何创建数据库连接和命令,该命令在首次请求该页时将数据绑定到 DataGrid 服务器控件。

void Page_Load(Object sender, EventArgs e)
{
if(!Page.IsPostBack) 
{}
}

  由于每次请求时都执行 Page_Load 事件,上述代码检查 IsPostBack 属性是否设置为 false。如果是,则执行代码。如果该属性设置为true,则不执行代码。

  注意 如果不运行这种检查,回发页的行为将不更改。Page_Load 事件的代码在执行服务器控件事件之前执行,但只有服务器控件事件的结果才可能在输出页上呈现。如果不运行该检查,仍将为 Page_Load 事件和该页上的任何服务器控件事件执行处理。

4、当不使用会话状态时禁用它,并且程序开发中尽量少用Session

  并不是所有的应用程序或 页都需要针对于具体用户的会话状态,您应该对任何不需要会话状态的应用程序或页禁用会话状态。

  若要禁用页的会话状态,请将 @ Page 指令中的 EnableSessionState 属性设置为 false。例如: <%@ Page EnableSessionState="false" %>

  注意 如果页需要访问会话变量,但不打算创建或修改它们,则将 @ Page 指令中的 EnableSessionState 属性设置为 ReadOnly。

   若要禁用应用程序的会话状态,请在应用程序 Web.config 文件的 sessionstate 配置节中将 mode 属性设置为 off。例如:<sessionstate mode="off" />

5、 合理使用DataGrid(在asp.net2.0中为GridView)控件

  DataGrid控件带有最强大的数据显示功能,还内置 了对数据的修改、删除、添加、分页等很多功能。如果只需简单的显示数据, DataGrid并非最佳选择。DataGrid控件的分页功能,数据的存储方式(存储在viewstate中)等,虽然让程序开发者使用方便快捷,但由 此产生的性能开销不容小视。

  DataList控件比DataGrid功能少了很多。但自定义性强了很多。特有的多行数据显示还是比较方 便的。DataGrid能实现的功能,它基本能实现。

  Repeater控件功能最少,但自定义性非常强。由于减少了很多功能,对服务器 的性能带来消耗最小。

  因此,在只需简单显示数据列表时,选择Repeater或DataList控件同样可以达到目的,而且减轻了性能 上的开销。

建议选择顺序:Repeater然后DataList最后DataGrid(GridView)

6、对数据进行分 页

  ASP.NET的DataGrid(在asp.net2.0中为GridView)有一个非常有用的功能:分页。如果 DataGrid允许分页,在某一时刻它只下载某一页的数据,另外,它有一个数据分页的浏览导航栏,它让你可以选择浏览某一页,而且每次只下载一页的数 据。

  但是它有一个小小的缺点,就是你必须把所有的数据都绑定到DataGrid中。也就是说,你的数据层必须返回所有的数据,然后 DataGrid再根据当前页过滤出当前页所需要的数据显示出来。如果有一个一万条记录的结果集要用DataGrid进行分页,假设DataGrid每页 只显示25条数据,那就意味着每次请求都有9975条数据都是要丢弃的。每次请求都要返回这么大的数据集,对应用程序的性能影响是非常大的。

   一个好的解决方案是写一个分页的存储过程,
如:

CREATE PROCEDURE dbo.sp_DataPages 
@Sql nVARCHAR(2000), 
@PK varchar(50), --主键字段名(可以是任何数据类型;不能,并且也不需要带表名前缀,如:不可以是users.id)
@Order varchar(50), --排序方式(带desc或asc,可以是多个组合;不能,并且也不需要带表名前缀,如:不可以是users.id desc)
@Page int, 
@PageSize int = 30 
AS

set nocount on

DECLARE @Str nVARCHAR(4000)

if(@Page=1)
SET @Str= ‘Select Top ‘+ CAST((@PageSize) As VARCHAR(20)) + ‘ * From (‘+ @Sql + ‘) As table1 Order By table1.‘ + @Order
else 
SET @Str= ‘Select Top ‘+ CAST((@PageSize) As VARCHAR(20)) + ‘ * From (‘+ @Sql + ‘) As table1 Where table1.‘ + @PK + ‘ Not In (Select Top ‘ + CAST((@PageSize*(@Page-1)) AS VARCHAR(20)) + ‘ ‘ + @PK + ‘ From (‘ + @Sql + ‘) As table2 Order By table2.‘ + @Order + ‘ ) Order By table1.‘ + @Order

--print @str 
--exec (@Str)
EXEC sp_ExecuteSql @Str

set nocount off

Go

或者,使用sql server 2005中的row_number()函数

declare @sql varchar(8000)

set @sql=‘select *‘
+‘ from‘ 
+‘ (‘

+‘ select row_number() over (order by id desc) as rowNumber,*‘ 
+‘ from Users‘ 
+‘ where id>0 and name<>‘‘‘‘‘

+‘ )‘ 
+‘ as table1‘

+‘ where rowNumber between ‘+str((@page-1)*@pagesize+1)+‘ AND ‘+str(@page*@pagesize)
+‘ order by id desc‘

--exec (@sql) 
EXEC sp_ExecuteSql @sql

(小技巧:将记 录总数保为Cache或Session来提高分页性能。)

7、不要禁用 Web 窗体页的缓冲

除非有特殊的原因要关闭缓冲, 否则使其保持打开。禁用 Web 窗体页的缓冲会导致大量的性能开销。

启用页面输出的缓冲区(Buffer)
如果Buffer的机制被关闭,可以用下面的方法打开。
使用程序打开页面输出缓存: 
Response.BufferOutput = true;

使用@Page开关打开页面输出缓冲机制: 
<%@ Page Buffer = "true" %>

使用 Web.config或Machine.config配置文件的<pages>节点:
<pages buffer="true"/>

8、设置page的smart navigation属性

smart navigation设置为true能让用户明显的感觉性能提高。启用此属性后对客户端和服务端影响不大.它能智能刷新需要刷新的部分。

在 大多数情况下不要在代码中设置该属性。 
在 .aspx 文件的 @ Page 指令中将 SmartNavigation 属性设置为 true。请求该页时,动态生成的类将设置该属性。

Internet Explorer 5 或更高版本浏览器请求页时(或稍后),智能导航将通过执行下列功能提高用户对该页的操作能力: 
消除导航导致的闪烁。
从 一页移动到另一页时保持滚动位置。 
保持导航之间的元素焦点。
在 浏览器的历史记录中只保留最后一页的状态。

智能导航最适用于需要频繁回发,但是其内容在返回时不会发生显著更改的 ASP.NET 页。在决定是否将该属性设置为 true 时,请仔细考虑这一点。

三、c#(或vb.net)程序改进

1、使用值类型的ToString方法

   在连接字符串时,经常使用"+"号直接将数字添加到字符串中。这种方法虽然简单,也可以得到正确结果,但是由于涉及到不同的数据类型,数字需要通过装箱 操作转化为引用类型才可以添加到字符串中。但是装箱操作对性能影响较大,因为在进行这类处理时,将在托管堆中分配一个新的对象,原有的值复制到新创建的对 象中。

  使用值类型的ToString方法可以避免装箱操作,从而提高应用程序性能。

int num=1; 
string str="go"+num.ToString();

2、运用StringBuilder类

  String类对象是不可改 变的,对于String对象的重新赋值在本质上是重新创建了一个String对象并将新值赋予该对象,其方法ToString对性能的提高并非很显著。

   在处理字符串时,最好使用StringBuilder类,其.NET 命名空间是System.Text。该类并非创建新的对象,而是通过Append,Remove,Insert等方法直接对字符串进行操作,通过 ToString方法返回操作结果。

  其定义及操作语句如下所示:

int num;

System.Text.StringBuilder str = new System.Text.StringBuilder(); //创建字符串

str.Append(num.ToString()); //添加数值num

Response.Write(str.ToString); //显示操作结果

3、使用 HttpServerUtility.Transfer 方法在同一应用程序的页面间重定向

  采用 Server.Transfer 语法,在页面中使用该方法可避免不必要的客户端重定向(Response.Redirect)。

4、避免使用ArrayList。

因 为任何对象添加到ArrayList都要封箱为System.Object类型,从ArrayList取出数据时,要拆箱回实际的类型。建议使用自定义的 集合类型代替ArrayList。asp.net 2.0提供了一个新的类型,叫泛型,这是一个强类型,使用泛型集合就可以避免了封箱和拆箱的发生,提高了性能。

5、使用HashTale代 替其他字典集合类型
(如 StringDictionary,NameValueCollection,HybridCollection),存放少量数据的时候可以使用 HashTable.

转载至 http://blog.csdn.net/t_long/article/details/5610186

时间: 2024-10-23 03:32:40

.NET程序优化的相关文章

【转】CUDA程序优化要点

CUDA程序优化应该考虑的点:精度:只在关键步骤使用双精度,其他部分仍然使用单精度浮点以获得指令吞吐量和精度的平衡: 目前 GPU 的单精度性能要远远超过双精度性能,整数乘法.求模.求余等运算的指令吞吐量也较为有限.在科学计算中,由于需要处理的数据量巨大,往往采用双精度或者四精度才能获得可靠的结果,目前的 Tesla 架构还不能很好的满足高精度计算的需要.如果你的计算需要很高的精度,或者需要进行很多轮的迭代,最好考虑在关键的步骤中使用双精度,而在其他部分仍然使用单精度浮点以获得指令吞吐量和精度的

GPU 编程入门到精通(五)之 GPU 程序优化进阶

博主因为工作其中的须要,開始学习 GPU 上面的编程,主要涉及到的是基于 GPU 的深度学习方面的知识.鉴于之前没有接触过 GPU 编程.因此在这里特地学习一下 GPU 上面的编程. 有志同道合的小伙伴,欢迎一起交流和学习.我的邮箱: [email protected] .使用的是自己的老古董笔记本上面的 Geforce 103m 显卡,尽管显卡相对于如今主流的系列已经很的弱,可是对于学习来说.还是能够用的.本系列博文也遵从由简单到复杂,记录自己学习的过程. 0. 文件夹 GPU 编程入门到精通

大页内存(HugePages)在通用程序优化中的应用

今天给大家介绍一种比较新奇的程序性能优化方法-大页内存(HugePages),简单来说就是通过增大操作系统页的大小来减小页表,从而避免快表缺失.这方面的资料比较贫乏,而且网上绝大多数资料都是介绍它在Oracle数据库中的应用,这会让人产生一种错觉:这种技术只能在Oracle数据库中应用.但其实,大页内存可以算是一种非常通用的优化技术,应用范围很广,针对不同的应用程序,最多可能会带来50%的性能提升,优化效果还是非常明显的.在本博客中,将通过一个具体的例子来介绍大页内存的使用方法. 在介绍之前需要

面向处理器结构的程序优化

近两年从同事那里学了不少代码优化方法,在此总结一下. 面向处理器结构的优化可以从以下几个方向入手:缓存命中,指令预测,数据预取,数据对齐,内存拷贝优化,ddr访问延迟,硬件内存管理优化,指令优化,编译器优化等级以及性能描述工具. 缓存未命中是处理器的主要性能瓶颈之一.在FSL的powerpc上,访问一级缓存是3个时钟周期,二级是12个,3级30多个,内存100个以上.一级缓存和内存访问速度差30多倍.我们可以算一下,如果只有一级缓存和内存,100条存取指令,100%命中和95%命中,前者300周

ASP.NET 程序优化

一.SqlDataRead和Dataset的选择 Sqldataread优点:读取数据非常快.如果对返回的数据不需做大量处理的情况下,建议使用SqlDataReader,其性能要比datset好很多.缺点:直到数据读完才可close掉于数据库的连接 (SqlDataReader 读数据是快速向前的.SqlDataReader 类提供了一种读取从 SQL Server 数据库检索的只进数据流的方法.它使用 SQL Server 的本机网络数据传输格式从数据库连接直接读取数据.DataReader需

GPU 编程入门到精通(四)之 GPU 程序优化

博主因为工作其中的须要,開始学习 GPU 上面的编程,主要涉及到的是基于 GPU 的深度学习方面的知识,鉴于之前没有接触过 GPU 编程.因此在这里特地学习一下 GPU 上面的编程.有志同道合的小伙伴.欢迎一起交流和学习,我的邮箱: [email protected] . 使用的是自己的老古董笔记本上面的 Geforce 103m 显卡,尽管显卡相对于如今主流的系列已经很的弱.可是对于学习来说,还是能够用的.本系列博文也遵从由简单到复杂.记录自己学习的过程. 0. 文件夹 GPU 编程入门到精通

LabVIEW程序优化相关技巧

最近在做毕设最后一点优化工作收尾,对于程序优化仍是一个很虚无缥缈的概念和过程.参考了相关书籍,记录如下: 从增加程序运行速度和效率的角度: 1.执行处禁止VI调试可以大大提高VI运行速度,降低内存利用. 2.根据实际需要选择短数据类型,节约空间,提高效率.注意溢出即可. 3.循环中加入几十至几百毫秒的延时,避免作无谓的运算. 4.文件的读写放在循环外. 5.涉及界面刷新的相关属性节点放在循环外. 6.局部变量.全局变量的读写放在循环外. 7.利用等待用户反馈的时间做下一步工作. 进一步从内存的角

Android程序优化-----JAVA类的生命周期

前言: 虚拟机.类在内存中干了什么?这是对程序优化的前提知识吧!想写个程序优化的系列文章,主要写的通俗些让人一看就懂,当然严谨性就降低了.毕竟我不太可能开发虚拟机嘛!如果要自己研究还是看<深入理解Java虚拟机>这本神书吧.吐三升血来推荐这本书,这本书把.class文件.虚拟机构造.如何执行.如何优化讲的淋漓尽致. 虚拟机构造: 运行时数据区域(JAVA虚拟机在内存中划分的几个区域): 你想想啊!我们写的.java文件编译后形成.class文件.java中的类名A.方法名.常量CONSTANT

记一次获得 3 倍性能的 go 程序优化实践,及 on-cpu / off-cpu 火焰图的使用

转自:https://mp.weixin.qq.com/s/9IKaXeWTiiQTFlvZzxgsEA 记一次获得 3 倍性能的 go 程序优化实践,及 on-cpu / off-cpu 火焰图的使用 原创 2017-07-27 petergz 唯技术 先把结论列在前面: 1.Golang的性能可以做到非常好,但是一些native包的性能很可能会拖后腿,比如regexp和encoding/json.如果在性能要求较高的场合使用,要根据实际情况做相应优化. 2.on-cpu/off-cpu火焰图

程序优化的5个方向

程序优化的5个方向 80/20法则:程序执行中,80%的时间消耗在20%的代码上. 优化前,我们首先得找到这20%的关键路径: 各种语言都有专门的工具来找到这20%的关键路径,比如C++经常用到的gprof: 参考<C++的性能优化实践> 在关键路径上对耗时的计算进行优化: 主要的优化方向为: 减少重复计算.预先计算.延后计算.降低计算代价.不计算: 减少重复计算 典型的例子如缓存,将之前相同的计算(查数据库,读写文件)存下来,等待下一次继续使用: 适用场景:计算结果有有效期,过段时间后需要再