提高.NET网站的性能

比如说到dataset.从网上看到一些关于性能优化的文章
1、 利用索引加快查找行的效率
如果需要反复查找行,建议增加索引。有两种方式:
1)设置DataTable的PrimaryKey
    适用于按PrimaryKey查找行的情况。注意此时应调用DataTable.Rows.Find方法,一般惯用的Select方法不能利用索引。
2)使用DataView
    适用于按Non-PrimaryKey查找行的情况。可为DataTable创建一个DataView,并通过SortOrder参数指示建立索引。此后使用Find或FindRows查找行。


一、减少往返行程(Reduce Round Trips)
    使用下面的方法可以减少Web服务器和Browser之间的往返行程:
    1、为Browser启用缓存
    如果呈现的内容是静态的或变化周期较长,应启用Browser缓存,避免发出冗余的http请求。
    2、缓冲页面输出
    如果可能,则尽量缓冲页面输出,处理结束后再一次传送到客户端,这可以避免频繁传递小块内容所造成的多次网络交互。由于这种方式在页面处理结束之前客户端无法看到页面内容,因此如果一个页面的尺寸较大的话,可考虑使用Response.Flush方法。该方法强制输出迄今为止在缓冲区中的内容,你应当采用合理的算法控制调用Response.Flush方法的次数。

    3、使用Server.Transfer重定向请求
    使用Server.Transfer方法重定向请求优于Response.Redirect方法。原因是Response.Redirect会向Broswer回送一个响应头,在响应头中指出重定向的URL,之后Brower使用新的URL重新发出请求。而Server.Transfer方法直接是一个简单的服务端调用,完全没有这些开销!
    需要注意Server.Transfer有局限性:第一,它会跳过安全检查;第二,只适用于在同一Web应用内的页面间跳转。

二、避免阻塞和长时间的作业
    如果需要运行阻塞或长时间运行的操作,可以考虑使用异步调用的机制,以便Web服务器能够继续处理其它的请求。
    1、使用异步方式调用Web服务和远程对象
    只要有可能就要避免在请求的处理过程中对Web服务和远程对象的同步调用,因为它占用的是的ASP.NET 线程池中的工作线程,这将直接影响Web服务器响应其它请求的能力。

    2、考虑给不需要返回值的Web方法或远程对象的方法添加OneWay属性
    这种模式能让Web Server调用之后就立即返回。可根据实际情况决定是否使用这种方法。

    3、使用工作队列
    将作业提交到服务器上的工作队列中。客户端通过发送请求来轮询作业的执行结果。

三、 使用缓存
    缓存能在很大程度上决定ASP.NET应用的最终性能。Asp.net支持页面输出缓存和页面部分缓存,并提供Cache API,供应用程序缓存自己的数据。是否使用缓存可考虑下面的要点:
    1、识别创建与访问代价较大的数据
    2、评估需要缓存数据的易变性
    3、评估数据的使用频次
    4、 将要缓存数据中易变数据和不变数据分离,只缓存不变数据
        5、选择合适的缓存机制(除Asp.net Cache外,Application state和Session state也可以作为缓存使用)

四、多线程
    1、避免在请求处理过程中创建线程
    在执行请求的过程中创建线程是一种代价较大的操作,会严重影响Web Server的性能。如果后续的操作必须用线程完成,建议通过thread pool来创建/管理线程。

    2、不要依赖线程数据槽或线程静态变量
    由于执行请求的线程是ASP.NET thread pool中的工作线程,同一个Client的两次请求不一定由相同的线程来处理。

    3、避免阻塞处理请求的线程

    4、避免异步调用
    这和1的情况类似。异步调用会导致创建新的线程,增加服务器的负担。所以,如果没有并发的作业要执行,就不要执行异步调用。

五、 系统资源
    1、考虑实现资源池以提升性能
    2、明确地调用Dispose或Close释放系统资源
    3、不要缓存或长时间占用资源池中的资源
    4、尽可能晚的申请,尽可能早的释放

六、 页面处理
    1、尽量减小Page的尺寸
    包括缩短控件的名称、CSS的class的名称、去掉无谓空行和空格、禁用不需要的ViewState
    2、启用页面输出的缓冲区(Buffer)
    如果Buffer的机制被关闭,可以用下面的方法打开。
    使用程序打开页面输出缓存:
      Response.BufferOutput = true;
    使用@Page开关打开页面输出缓冲机制:
      <%@ Page Buffer = "true" %>

    使用Web.config或Machine.config配置文件的 <pages>节点:
      <pages buffer="true" …>
    3、利用Page.IsPostBack优化页面输出
    4、通过分离页面的不同的内容,来提高缓存效率和减少呈现的时间
    5、优化复杂和代价较大的循环
    6、合理利用客户端的计算资源,将一些操作转移到客户端进行

七、 ViewState
    ViewState是Asp.net为服务端控件在页面回传之间跟踪状态信息而设计的一种机制。
  1. 关闭ViewState
    如果不需要跟踪页面状态,例如页面不会 回传(PostBack)、不需要处理服务端控件事件或者每次页面刷新时都会重新计算控件内容,那么就不需要用ViewState来记录页面状态了。可以对特定的WebControl设置EnableViewState属性,也可以在页面一级设置:
    <%@ Page EnableViewState="false" %>

    2、在恰当的时间点初始化控件属性
    ASP.NET的控件在执行构造函数、初始化的期间设置的属性不会被跟踪变化;而在初始化阶段之后对属性的修改都会被跟踪,并最终记录到IE页面的__VIEWSTATE之中。所以,选择合理的初始化控件属性的执行点,能有效的减小页面尺寸。

    3、谨慎选择放到ViewState中的内容
    放到ViewState中的内容会被序列化/反序列化,Asp.net为String、Integer、Boolean等基本类型的序列化做了优化,如果Array、ArrayList、HashTable存储的是基本类型效率也较高,但其它类型则需要提供类型转换器(Type Converter),否则将使用代价昂贵的二进制序列化程序。

 

 

 

 

 

一条足够烂的sql语句就能把你所有的优化工作废掉,数据库优化,这个应该排第一
缓存是所有web架构师的首选优化工具 。这个可以排第二

 

数据库优化很关键
网站运行的过程就是与数据库不断通信的过程

 

使用存储过程

使用缓存

尽量少调用业务逻辑

加大硬件资源投入

用完即释放内存资源

说来说去应该也就是这些吧.

 

尽量少用一些flash和大图片,滤镜,等等一些耗时,不切实际的东西

 

1。数据库优化。根据实际情况合理设计好数据表。
2。页面缓存。近来减少与数据库之间的连接次数。
3。页面图片不能太大,或者尽量少用图片,flash。
4。能使用存储过程尽量使用存储过程。

 

1.缓存。 (技术可以,用缓存池)
2.线程池。
3.图片分流。
4.样式图片组合成一张图片调用。
5.div+ul+li+css 设计网页
6.少用服务端控件。比如:gridview ,可以生成HTML,而无需用gridview

 

我认为.net网站真正的快速之道是:
1、前台用html表现,后台用ashx实现业务逻辑
2、html以Ajax方式连接ashx实现页面数据变化
优势是:即使网速慢或数据访问层效率低,也会被屏蔽,让用户感觉不到等待。
这种设计适合中小网站,且页面有频繁的数据交互情况。
很明显,这就是对过去传统CGI的再发挥,呵呵,现在很多年轻人可能不知道传统CGI是什么了吧,到是总听说PHP的CGI。
如果页面数据交互很少,仅是表现的话,那么可以直接生成纯静态页面。
这样的网站速度肯定是飞快的。

 

1)避免使用ArrayList。
    因为任何对象添加到ArrayList都要封箱为System.Object类型,从ArrayList取出数据时,要拆箱回实际的类型。建议使用自定义的集合类型代替ArrayList。.net 2.0提供了一个新的类型,叫泛型,这是一个强类型,使用泛型集合就可以避免了封箱和拆箱的发生,提高了性能。
2)使用HashTale代替其他字典集合类型(如StringDictionary,NameValueCollection,HybridCollection),存放少量数据的时候可以使用HashTable.
3)为字符串容器声明常量,不要直接把字符封装在双引号" "里面。
      //避免
      MyObject obj = new MyObject();
      obj.Status = "ACTIVE";

      //推荐
      const string C_STATUS = "ACTIVE";
      MyObject obj = new MyObject();
      obj.Status = C_STATUS;

4) 不要用UpperCase,Lowercase转换字符串进行比较,用String.Compare代替,它可以忽略大小写进行比较.
 
  例:
      const string C_VALUE = "COMPARE";
      if (String.Compare(sVariable, C_VALUE, true) == 0)
      {
      Console.Write("SAME");
      }

 

 


把数据序列化为二进制文件方便传输。
    我们在处理DataSet,DataTable对象时可以序列化为XML文件,如果要在网络传输,XML文件会产生内存,网络带宽等资源问题。这时我们就可以把它序列化为二进制文件,这样生成的文件会减少很多,代码如下:
      FileStream fs = new fileStream(@"XMLData.bin",FileMode.Create);
      BinaryFormatter bf = new BinaryFormatter();
      bf.Serialize(fs,XMLData);
      fs.colse();
    这样生成的二进制文件称为XMLBinary,用WINHEX直接打开还可以看到一些XML标记在里面,如果数据量很大,这时加一行代码:
    XMLData.RemortingFormat = SerializationFormat.Binary;
    这时生成的文件称为TrueBinary文件,当处理大量(超过10000行)时生成的文件尺寸是XMLBinary的几分之一。序列化的时候会自动保存模式,这样解序过程很简单。我还不知道解序比直接读取XML性能会下降多少。
使用DataTable的ImportRow方法。
      有些场合需要把大量数据从一个DataTable复制到另一个DataTable,使用DataTable的ImportRow方法可以大大提高性能,数据量少时没多大分别,当数据量到一万行以上时就可以明显的提高,可以达到几倍。

 

 

集中执行sql语句,
如:insert into aa(name)values('');select * form bb;

复杂的查询配合程序执行,
如:select * from users where name like '%abc%'
改成:select * from users
foreach datarow row in dt.rows
if row["name"].contains("abc") ..

 

 

一、        缓存
缓存是ASP.NET中提高性能的重要手段,缓存一般遵循以下原则:
1)  在页面中将静态内容与动态内容分割开来
考虑将动态内容作成用户控件
2)  缓存合理的数据
一般应当缓存应用程序集的数据、多个用户共同使用的数据、静态数据、生成数据需要很大开销的动态数据、DataSet以及自定义对象等。不要缓存数据库连接对象、DataReader。
3)  选择适当的方式
如可以使用页面缓存指令,API等。
二、        视图状态
视图状态放在页面中名为_VIEWSTATE的表单隐藏域里面,随页面一起被发送到客户端,在用户提交页面时,又被提交到服务器。
1)  如果不需要视图状态,则禁用
视图状态默认是允许的,如果页面不进行PostBack,如果不处理服务器控件的事件,如果服务器控件的数据每次都需要重新计算等
2)  尽量减少视图状态中存放的对象
三、        关于页面处理(减少页面生成的时间和过程)
1)              应尽量减少页面文件的大小
2)              通过检测Page.IsPostBack减少代码执行的数量
3)              禁止使用Debug=“true”,减少页面生成过程中生成额外的调试信息
4)              使用Server.Transfer而不使用Response.Redirect,减少服务器和客户端间的往返
5)              尽量使用客户端验证,减少服务器和客户端间的往返
6)              在适当的场合使用服务器控件
7)              尽量避免嵌套的服务器控件
四、        避免使用Page.DataBind和DataBinder.Eval
五、        关于Application对象和Session对象
1)  使用静态属性存储数据而不使用Application对象,在Application对象里存储只读类型的数据都将回提高性能
2)  尽量使用InProc模式的Session,这个模式是最快的
3)  在Session里存储基本类型的数据减少序列化的所消耗的资源
4)  如果不用Session变量,使用EnvableViewState=“false”禁用
5)  如果不修改Session变量的值,尽量使用ReadOnly属性设置
六、        关于字符串操作
1)  尽量使用Response.Write将结果输出到浏览器,这种方法是最快的。不要将字符串连接在一起一次输出。
2)  在字符串短并且少的情况下可以使用String.Concat方法,而在字符串长度未知,并且字符串大的情况下,使用StringBuilder对象
3)  不要使用strVar==“”来判断字符串是否为“”,这样它会创建额外的字符串,请使用strVar==String.Empty代替或者使用strVar.Length==0来判断
4)  请使用String.Compare方法进行字符串的比较
七、        关于数据访问
1)  尽量使用存储过程返回数据,不要直接在代码中进行查询
2)  在数据库中只返回有用的数据结果,不要选择不使用的数据字段
3)  进行使用DataReader进行数据绑定,DataReader是单向只读的
4)  尽量一次返回多个数据集而不是每个记录集分别打开一次数据库连接进行查询
5)  尽量晚的打开数据库,尽量早的关闭数据库
6)  使用连接池提高性能
7)  使用ExecuteNonQuery方法执行不返回数据的操作,使用ExecuteScalar方法返回单个结果的操作,使用CommandBehavior.Sequentialaccess返回二进制数据或者大数据
8)  如果多次相同的查询,请使用Command.Prepare方法
9)  使用GetOrdinal方法预先得到索引值,使用索引值比使用字符串的列名查询数据效率更高
八、        关于代码优化
1)  在解析基本数据类型时,使用Try方法如果解析失败,会抛出异常,使用TryParse方法则只执行Else下的语句。
2)  使用AppendAllText、WriteAllBytes等方法读写文件内容可以优化性能
3)  将循环判定条件放在for语句外
4)  避免在循环里创建对象
5)  尽量减少装箱的次数
6)  不要使用例外控制程序的流程
7)  在循环中不要使用不变的对象属性或者字段
8)  使用for循环代替foreach循环遍历结合内容
9)  数组是所有集合中最快的,如果没有特殊需要,尽量使用数组代替集合
10)    了解各个集合类型的特性,选择合适的类型
11)    使用泛型避免减少装箱、拆箱

 

 

1. 数据库访问性能优化
 
    数据库的连接和关闭
 
    访问数据库资源需要创建连接、打开连接和关闭连接几个操作。这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源。ASP.NET中提供了连接池(Connection Pool)改善打开和关闭数据库对性能的影响。系统将用户的数据库连接放在连接池中,需要时取出,关闭时收回连接,等待下一次的连接请求。
 
 
    连接池的大小是有限的,如果在连接池达到最大限度后仍要求创建连接,必然大大影响性能。因此,在建立数据库连接后只有在真正需要操作时才打开连接,使用完毕后马上关闭,从而尽量减少数据库连接打开的时间,避免出现超出连接限制的情况。
 
    使用存储过程
 
    存储过程是存储在服务器上的一组预编译的SQL语句,类似于DOS系统中的批处理文件。存储过程具有对数据库立即访问的功能,信息处理极为迅速。使用存储过程可以避免对命令的多次编译,在执行一次后其执行规划就驻留在高速缓存中,以后需要时只需直接调用缓存中的二进制代码即可。
 
    另外,存储过程在服务器端运行,独立于ASP.NET程序,便于修改,最重要的是它可以减少数据库操作语句在网络中的传输。
 
    优化查询语句
 
    ASP.NET中ADO连接消耗的资源相当大,SQL语句运行的时间越长,占用系统资源的时间也越长。因此,尽量使用优化过的SQL语句以减少执行时间。比如,不在查询语句中包含子查询语句,充分利用索引等。
 
  2. 字符串操作性能优化
 
    使用值类型的ToString方法
 
    在连接字符串时,经常使用"+"号直接将数字添加到字符串中。这种方法虽然简单,也可以得到正确结果,但是由于涉及到不同的数据类型,数字需要通过装箱操作转化为引用类型才可以添加到字符串中。但是装箱操作对性能影响较大,因为在进行这类处理时,将在托管堆中分配一个新的对象,原有的值复制到新创建的对象中。
 
    使用值类型的ToString方法可以避免装箱操作,从而提高应用程序性能。
 
    运用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. 优化 Web 服务器计算机和特定应用程序的配置文件以符合您的特定需要
 
    默认情况下,ASP.NET 配置被设置成启用最广泛的功能并尽量适应最常见的方案。因此,应用程序开发人员可以根据应用程序所使用的功能,优化和更改其中的某些配置,以提高应用程序的性能。下面的列表是您应该考虑的一些选项。
 
    仅对需要的应用程序启用身份验证。默认情况下,身份验证模式为 Windows,或集成 NTLM。大多数情况下,对于需要身份验证的应用程序,最好在 Machine.config 文件中禁用身份验证,并在 Web.config 文件中启用身份验证。
 
    根据适当的请求和响应编码设置来配置应用程序。ASP.NET 默认编码格式为 UTF-8。如果您的应用程序为严格的 ASCII,请配置应用程序使用 ASCII 以获得稍许的性能提高。
 
    考虑对应用程序禁用 AutoEventWireup。在 Machine.config 文件中将 AutoEventWireup 属性设置为 false,意味着页面不将方法名与事件进行匹配和将两者挂钩(例如 Page_Load)。如果页面开发人员要使用这些事件,需要在基类中重写这些方法(例如,需要为页面加载事件重写 Page.OnLoad,而不是使用 Page_Load 方法)。如果禁用 AutoEventWireup,页面将通过将事件连接留给页面作者而不是自动执行它,获得稍许的性能提升。
 
    从请求处理管线中移除不用的模块。默认情况下,服务器计算机的 Machine.config 文件中 <httpModules> 节点的所有功能均保留为激活。根据应用程序所使用的功能,您可以从请求管线中移除不用的模块以获得稍许的性能提升。检查每个模块及其功能,并按您的需要自定义它。
 
    例如,如果您在应用程序中不使用会话状态和输出缓存,则可以从 <httpModules>列表中移除它们,以便请求在不执行其他有意义的处理时,不必执行每个模块的进入和离开代码。
 
  4. 一定要禁用调试模式
 
    在部署生产应用程序或进行任何性能测量之前,始终记住禁用调试模式。如果启用了调试模式,应用程序的性能可能受到非常大的影响。
 
  5. 对于广泛依赖外部资源的应用程序,请考虑在多处理器计算机上启用网络园艺
 
    ASP.NET 进程模型帮助启用多处理器计算机上的可缩放性,将工作分发给多个进程(每个 CPU 一个),并且每个进程都将处理器关系设置为其 CPU。此技术称为网络园艺。如果应用程序使用较慢的数据库服务器或调用具有外部依赖项的 COM 对象(这里只是提及两种可能性),则为您的应用程序启用网络园艺是有益的。但是,在决定启用网络园艺之前,您应该测试应用程序在网络园中的执行情况。
 
  6. 只要可能,就缓存数据和页输出
 
    ASP.NET 提供了一些简单的机制,它们会在不需要为每个页请求动态计算页输出或数据时缓存这些页输出或数据。另外,通过设计要进行缓存的页和数据请求(特别是在站点中预期将有较大通讯量的区域),可以优化这些页的性能。与 .NET Framework 的任何 Web 窗体功能相比,适当地使用缓存可以更好的提高站点的性能,有时这种提高是超数量级的。
 
    使用 ASP.NET 缓存机制有两点需要注意。首先,不要缓存太多项。缓存每个项均有开销,特别是在内存使用方面。不要缓存容易重新计算和很少使用的项。其次,给缓存的项分配的有效期不要太短。很快到期的项会导致缓存中不必要的周转,并且经常导致更多的代码清除和垃圾回收工作。若关心此问题,请监视与 ASP.NET Applications 性能对象关联的 Cache Total Turnover Rate 性能计数器。高周转率可能说明存在问题,特别是当项在到期前被移除时。这也称作内存压力。
 
  7. 选择适合页面或应用程序的数据查看机制
 
    根据您选择在 Web 窗体页显示数据的方式,在便利和性能之间常常存在着重要的权衡。例如,DataGrid Web 服务器控件可能是一种显示数据的方便快捷的方法,但就性能而言它的开销常常是最大的。在某些简单的情况下,您通过生成适当的 HTML 自己呈现数据可能很有效,但是自定义和浏览器定向会很快抵销所获得的额外功效。Repeater Web 服务器控件是便利和性能的折衷。它高效、可自定义且可编程。
 
  8. 将 SqlDataReader 类用于快速只进数据游标
 
    SqlDataReader 类提供了一种读取从 SQL Server 数据库检索的只进数据流的方法。如果当创建 ASP.NET 应用程序时出现允许您使用它的情况,则 SqlDataReader 类提供比 DataSet 类更高的性能。情况之所以这样,是因为 SqlDataReader 使用 SQL Server 的本机网络数据传输格式从数据库连接直接读取数据。另外,SqlDataReader 类实现 IEnumerable 接口,该接口也允许您将数据绑定到服务器控件。有关更多信息,请参见 SqlDataReader 类。有关 ASP.NET 如何访问数据的信息,请参见通过 ASP.NET 访问数据。
 
  9. 将 SQL Server 存储过程用于数据访问
 
    在 .NET Framework 提供的所有数据访问方法中,基于 SQL Server 的数据访问是生成高性能、可缩放 Web 应用程序的推荐选择。使用托管 SQL Server 提供程序时,可通过使用编译的存储过程而不是特殊查询获得额外的性能提高。
 
  10. 避免单线程单元 (STA) COM 组件
 
    默认情况下,ASP.NET 不允许任何 STA COM 组件在页面内运行。若要运行它们,必须在 .aspx 文件内将 ASPCompat=true 属性包含在 @ Page 指令中。这样就将执行用的线程池切换到 STA 线程池,而且使 HttpContext 和其他内置对象可用于 COM 对象。前者也是一种性能优化,因为它避免了将多线程单元 (MTA) 封送到 STA 线程的任何调用。
 
    使用 STA COM 组件可能大大损害性能,应尽量避免。若必须使用 STA COM 组件,如在任何 interop 方案中,则应在执行期间进行大量调用并在每次调用期间发送尽可能多的信息。另外,小心不要在构造页面期间创建任何 STA COM 组件。例如下面的代码中,在页面构造时将实例化由某个线程创建的 MySTAComponent,而该线程并不是将运行页面的 STA 线程。这可能对性能有不利影响,因为要构造页面就必须完成 MTA 和 STA 线程之间的封送处理。
 
  <%@ Page Language="VB" ASPCompat="true" %>
 
  <script runat=server>
 
  Dim myComp as new MySTAComponent()
 
  Public Sub Page_Load()
 
  myComp.Name = "Bob"
 
  End Sub
 
  </script>
 
  <html>
 
  <%
 
  Response.Write(myComp.SayHello)
 
  %>
 
  </html>
 
    首选机制是推迟对象的创建,直到以后在 STA 线程下执行上述代码,如下面的例子所示。
 
  <%@ Page Language="VB" ASPCompat="true" %>
 
  <script runat=server>
 
  Dim myComp
 
  Public Sub Page_Load()
 
  myComp = new MySTAComponent()
 
  myComp.Name = "Bob"
 
  End Sub
 
  </script>
 
  <html>
 
  <%
 
  Response.Write(myComp.SayHello)
 
  %>
 
  </html>
 
    推荐的做法是在需要时或者在 Page_Load 方法中构造任何 COM 组件和外部资源。
 
    永远不要将任何 STA COM 组件存储在可以由构造它的线程以外的其他线程访问的共享资源里。这类资源包括像缓存和会话状态这样的资源。即使 STA 线程调用 STA COM 组件,也只有构造此 STA COM 组件的线程能够实际为该调用服务,而这要求封送处理对创建者线程的调用。此封送处理可能产生重大的性能损失和可伸缩性问题。在这种情况下,请研究一下使 COM 组件成为 MTA COM 组件的可能性,或者更好的办法是迁移代码以使对象成为托管对象。
 
  11. 将调用密集型的 COM 组件迁移到托管代码
 
    .NET Framework 提供了一个简单的方法与传统的 COM 组件进行交互。其优点是可以在保留现有投资的同时利用新的平台。但是在某些情况下,保留旧组件的性能开销使得将组件迁移到托管代码是值得的。每一情况都是不一样的,决定是否需要迁移组件的最好方法是对 Web 站点运行性能测量。建议您研究一下如何将需要大量调用以进行交互的任何 COM 组件迁移到托管代码。
 
    许多情况下不可能将旧式组件迁移到托管代码,特别是在最初迁移 Web 应用程序时。在这种情况下,最大的性能障碍之一是将数据从非托管环境封送到托管环境。因此,在交互操作中,请在任何一端执行尽可能多的任务,然后进行一个大调用而不是一系列小调用。例如,公共语言运行库中的所有字符串都是 Unicode 的,所以应在调用托管代码之前将组件中的所有字符串转换成 Unicode 格式。
 
    另外,一处理完任何 COM 对象或本机资源就释放它们。这样,其他请求就能够使用它们,并且最大限度地减少了因稍后请求垃圾回收器释放它们所引起的性能问题。

 

 

12. 在 Visual Basic .NET 或 JScript 代码中使用早期绑定
 
    以往,开发人员喜欢使用 Visual Basic、VBScript 和 JScript 的原因之一就是它们所谓“无类型”的性质。变量不需要显式类型声明,并能够简单地通过使用来创建它们。当从一个类型到另一个类型进行分配时,转换将自动执行。不过,这种便利会大大损害应用程序的性能。
 
    Visual Basic 现在通过使用 Option Strict 编译器指令来支持类型安全编程。为了向后兼容,默认情况下,ASP.NET 不启用该选项。但是,为了得到最佳性能,强烈建议在页中启用该选项。若要启用 Option Strict,请将 Strict 属性包括在 @ Page 指令中,或者,对于用户控件,请将该属性包括在 @ Control 指令中。下面的示例演示了如何设置该属性,并进行了四个变量调用以显示使用该属性是如何导致编译器错误的。
 
  <%@ Page Language="VB" Strict="true" %>
 
  <%
 
  Dim B
 
  Dim C As String
 
  ' This will cause a compiler error.
 
  A = "Hello"
 
  ' This will cause a compiler error.
 
  B = "World"
 
  ' This will not cause a compiler error.
 
  C = "!!!!!!"
 
  ' But this will cause a compiler error.
 
  C = 0
 
  %>
 
    JScript .NET 也支持无类型编程,但它不提供强制早期绑定的编译器指令。若发生下面任何一种情况,则变量是晚期绑定的:
 
    被显式声明为 Object。
 
    是无类型声明的类的字段。
 
    是无显式类型声明的专用函数或方法成员,并且无法从其使用推断出类型。
 
    最后一个差别比较复杂,因为如果 JScript .NET 编译器可以根据变量的使用情况推断出类型,它就会进行优化。在下面的示例中,变量 A 是早期绑定的,但变量 B 是晚期绑定的。
 
  var A;
 
  var B;
 
  A = "Hello";
 
  B = "World";
 
  B = 0;
 
    为了获得最佳的性能,当声明 JScript .NET 变量时,请为其分配一个类型。例如,var A : String。
 
  13. 使请求管线内的所有模块尽可能高效
 
    请求管线内的所有模块在每次请求中都有机会被运行。因此,当请求进入和离开模块时快速地触发代码至关重要,特别是在不使用模块功能的代码路径里。分别在使用及不使用模块和配置文件时执行吞吐量测试,对确定这些方法的执行速度非常有用。
 
  14. 使用 HttpServerUtility.Transfer 方法在同一应用程序的页面间重定向
 
    采用 Server.Transfer 语法,在页面中使用该方法可避免不必要的客户端重定向。
 
  15. 必要时调整应用程序每个辅助进程的线程数
 
    ASP.NET 的请求结构试图在执行请求的线程数和可用资源之间达到一种平衡。已知一个使用足够 CPU 功率的应用程序,该结构将根据可用于请求的 CPU 功率,来决定允许同时执行的请求数。这项技术称作线程门控。但是在某些条件下,线程门控算法不是很有效。通过使用与 ASP.NET Applications 性能对象关联的 Pipeline Instance Count 性能计数器,可以在 PerfMon 中监视线程门控。
 
    当页面调用外部资源,如数据库访问或 XML Web services 请求时,页面请求通常停止并释放 CPU。如果某个请求正在等待被处理,并且线程池中有一个线程是自由的,那么这个正在等待的请求将开始被处理。遗憾的是,有时这可能导致 Web 服务器上存在大量同时处理的请求和许多正在等待的线程,而它们对服务器性能有不利影响。通常,如果门控因子是外部资源的响应时间,则让过多请求等待资源,对 Web 服务器的吞吐量并无帮助。
 
    为缓和这种情况,可以通过更改 Machine.config 配置文件节点的 maxWorkerThreads 和 maxIOThreads 属性,手动设置进程中的线程数限制。
 
    注意 辅助线程是用来处理 ASP.NET 请求的,而 IO 线程则是用于为来自文件、数据库或 XML Web services 的数据提供服务的。
 
    分配给这些属性的值是进程中每个 CPU 每类线程的最大数目。对于双处理器计算机,最大数是设置值的两倍。对于四处理器计算机,最大值是设置值的四倍。无论如何,对于有四个或八个 CPU 的计算机,最好更改默认值。对于有一个或两个处理器的计算机,默认值就可以,但对于有更多处理器的计算机的性能,进程中有一百或两百个线程则弊大于利。
 
    注意 进程中有太多线程往往会降低服务器的速度,因为额外的上下文交换导致操作系统将 CPU 周期花在维护线程而不是处理请求上。
 
  16. 适当地使用公共语言运行库的垃圾回收器和自动内存管理
 
    小心不要给每个请求分配过多内存,因为这样垃圾回收器将必须更频繁地进行更多的工作。另外,不要让不必要的指针指向对象,因为它们将使对象保持活动状态,并且应尽量避免含 Finalize 方法的对象,因为它们在后面会导致更多的工作。特别是在 Finalize 调用中永远不要释放资源,因为资源在被垃圾回收器回收之前可能一直消耗着内存。最后这个问题经常会对 Web 服务器环境的性能造成毁灭性的打击,因为在等待 Finalize 运行时,很容易耗尽某个特定的资源。
 
  17. 如果有大型 Web 应用程序,可考虑执行预批编译
 
    每当发生对目录的第一次请求时都会执行批编译。如果目录中的页面没有被分析并编译,此功能会成批分析并编译目录中的所有页面,以便更好地利用磁盘和内存。如果这需要很长时间,则将快速分析并编译单个页面,以便请求能被处理。此功能带给 ASP.NET 性能上的好处,因为它将许多页面编译为单个程序集。从已加载的程序集访问一页比每页加载新的程序集要快。
 
    批编译的缺点在于:如果服务器接收到许多对尚未编译的页面的请求,那么当 Web 服务器分析并编译它们时,性能可能较差。为解决这个问题,可以执行预批编译。为此,只需在应用程序激活之前向它请求一个页面,无论哪页均可。然后,当用户首次访问您的站点时,页面及其程序集将已被编译。
 
    没有简单的机制可以知道批编译何时发生。需一直等到 CPU 空闲或者没有更多的编译器进程(例如 csc.exe(C# 编译器)或 vbc.exe(Visual Basic 编译器))启动。
 
    还应尽量避免更改应用程序的 \bin 目录中的程序集。更改页面会导致重新分析和编译该页,而替换 \bin 目录中的程序集则会导致完全重新批编译该目录。
 
    在包含许多页面的大规模站点上,更好的办法可能是根据计划替换页面或程序集的频繁程度来设计不同的目录结构。不常更改的页面可以存储在同一目录中并在特定的时间进行预批编译。经常更改的页面应在它们自己的目录中(每个目录最多几百页)以便快速编译。
 
    Web 应用程序可以包含许多子目录。批编译发生在目录级,而不是应用程序级。
 
  18. 不要依赖代码中的异常
 
    因为异常大大地降低性能,所以您不应该将它们用作控制正常程序流程的方式。如果有可能检测到代码中可能导致异常的状态,请执行这种操作。不要在处理该状态之前捕获异常本身。常见的方案包括:检查 null,分配给将分析为数字值的 String 一个值,或在应用数学运算前检查特定值。下面的示例演示可能导致异常的代码以及测试是否存在某种状态的代码。两者产生相同的结果。
 
  try
 
  {
 
  result = 100 / num;
 
  }
 
  catch (Exception e)
 
  {
 
  result = 0;
 
  }
 
  // ...to this.
 
  if (num != 0)
 
  result = 100 / num;
 
  else
 
  result = 0;
 
  19. 使用 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");
 
 
  20. 除非有特殊的原因要关闭缓冲,否则使其保持打开
 
    禁用 Web 窗体页的缓冲会导致大量的性能开销。
 
  21. 只在必要时保存服务器控件视图状态
 
    自动视图状态管理是服务器控件的功能,该功能使服务器控件可以在往返过程上重新填充它们的属性值(您不需要编写任何代码)。但是,因为服务器控件的视图状态在隐藏的窗体字段中往返于服务器,所以该功能确实会对性能产生影响。您应该知道在哪些情况下视图状态会有所帮助,在哪些情况下它影响页的性能。例如,如果您将服务器控件绑定到每个往返过程上的数据,则将用从数据绑定操作获得的新值替换保存的视图状态。在这种情况下,禁用视图状态可以节省处理时间。
 
    默认情况下,为所有服务器控件启用视图状态。若要禁用视图状态,请将控件的EnableViewState 属性设置为 false,如下面的 DataGrid 服务器控件示例所示。
 
  <asp:datagrid EnableViewState="false" datasource="..."
  runat="server"/>
 
    您还可以使用 @ Page 指令禁用整个页的视图状态。当您不从页回发到服务器时,这将十分有用:
 
  <%@ Page EnableViewState="false" %>
 
    注意 @ Control 指令中也支持 EnableViewState 属性,该指令允许您控制是否为用户控件启用视图状态。
 
    若要分析页上服务器控件使用的视图状态的数量,请(通过将 trace="true" 属性包括在 @ Page 指令中)启用该页的跟踪并查看 Control Hierarchy 表的 Viewstate 列。有关跟踪和如何启用它的信息,请参见 ASP.NET 跟踪。
 
  22. 避免到服务器的不必要的往返过程
 
    虽然您很可能希望尽量多地使用 Web 窗体页框架的那些节省时间和代码的功能,但在某些情况下却不宜使用 ASP.NET 服务器控件和回发事件处理。
 
    通常,只有在检索或存储数据时,您才需要启动到服务器的往返过程。多数数据操作可在这些往返过程间的客户端上进行。例如,从 HTML 窗体验证用户输入经常可在数据提交到服务器之前在客户端进行。通常,如果不需要将信息传递到服务器以将其存储在数据库中,那么您不应该编写导致往返过程的代码。
 
    如果您开发自定义服务器控件,请考虑让它们为支持 ECMAScript 的浏览器呈现客户端代码。通过以这种方式使用服务器控件,您可以显著地减少信息被不必要的发送到 Web 服务器的次数。
 
    使用 Page.IsPostBack 避免对往返过程执行不必要的处理
 
    如果您编写处理服务器控件回发处理的代码,有时可能需要在首次请求页时执行其他代码,而不是当用户发送包含在该页中的 HTML 窗体时执行的代码。根据该页是否是响应服务器控件事件生成的,使用 Page.IsPostBack 属性有条件地执行代码。例如,下面的代码演示如何创建数据库连接和命令,该命令在首次请求该页时将数据绑定到 DataGrid 服务器控件。
 
  void Page_Load(Object sender, EventArgs e)
 
  {
 
  // Set up a connection and command here.
 
  if (!Page.IsPostBack)
 
  {
 
  String query = "select * from Authors where FirstName like '%JUSTIN%'";
 
  myCommand.Fill(ds, "Authors");
 
  myDataGrid.DataBind();
 
  }
 
  }
 
 
    由于每次请求时都执行 Page_Load 事件,上述代码检查 IsPostBack 属性是否设置为 false。如果是,则执行代码。如果该属性设置为 true,则不执行代码。
 
    注意 如果不运行这种检查,回发页的行为将不更改。Page_Load 事件的代码在执行服务器控件事件之前执行,但只有服务器控件事件的结果才可能在输出页上呈现。如果不运行该检查,仍将为 Page_Load 事件和该页上的任何服务器控件事件执行处理。
 
  23. 当不使用会话状态时禁用它
 
    并不是所有的应用程序或页都需要针对于具体用户的会话状态,您应该对任何不需要会话状态的应用程序或页禁用会话状态。
 
    若要禁用页的会话状态,请将 @ Page 指令中的 EnableSessionState 属性设置为 false。例如:
 
  <%@ Page EnableSessionState="false" %>
 
    注意 如果页需要访问会话变量,但不打算创建或修改它们,则将 @ Page 指令中的 EnableSessionState 属性设置为 ReadOnly。
 
    还可以禁用 XML Web services 方法的会话状态。有关更多信息,请参见使用 ASP.NET 和 XML Web services 客户端创建的 XML Web services。
 
    若要禁用应用程序的会话状态,请在应用程序 Web.config 文件的 sessionstate 配置节中将 mode 属性设置为 off。例如:
 
  <sessionstate mode="off" />
 
 
  24. 仔细选择会话状态提供程序
 
    ASP.NET 为存储应用程序的会话数据提供了三种不同的方法:进程内会话状态、作为 Windows 服务的进程外会话状态和 SQL Server 数据库中的进程外会话状态。每种方法都有自己的优点,但进程内会话状态是迄今为止速度最快的解决方案。如果只在会话状态中存储少量易失数据,则建议您使用进程内提供程序。进程外解决方案主要用于跨多个处理器或多个计算机缩放应用程序,或者用于服务器或进程重新启动时不能丢失数据的情况。有关更多信息,请参见 ASP.NET 状态管理。
 
  25. 不使用不必要的Server Control
 
    ASP.net中,大量的服务器端控件方便了程序开发,但也可能带来性能的损失,因为用户每操作一次服务器端控件,就产生一次与服务器端的往返过程。因此,非必要,应当少使用Server Control。
 
  26. ASP.NET应用程序性能测试
 
    在对ASP.NET应用程序进行性能测试之前,应确保应用程序没有错误,而且功能正确。具体的性能测试可以采用以下工具进行:
 
    Web Application Strees Tool (WAS)是Microsoft发布的一个免费测试工具,可以从http://webtool.rte.microsoft.com/上下载。它可以模拟成百上千个用户同时对web应用程序进行访问请求,在服务器上形成流量负载,从而达到测试的目的,可以生成平均TTFB、平均TTLB等性能汇总报告。
 
    Application Center Test (ACT) 是一个测试工具,附带于Visual Studio.NET的企业版中,是Microsoft正式支持的web应用程序测试工具。它能够直观地生成图表结果,功能比WAS多,但不具备多个客户机同时测试的能力。
 
    服务器操作系统"管理工具"中的"性能"计数器,可以对服务器进行监测以了解应用程序性能。
 
  结论
 
    对于网站开发人员来说,在编写ASP.NET应用程序时注意性能问题,养成良好的习惯,提高应用程序性能,至少可以推迟必需的硬件升级,降低网站的成本。

 

邵志东老师 介绍的 《提高性能的实用技巧》
• 不要使用不必要的Session,和ASP中一样,
在不必要的时候不要使用Session
• 不使用不必要的Server Control
• 不使用不必要的ViewState
• 不要用Exception控制程序流程
• 禁用VB和Jscript动态数据类型
• 使用存储过程完成数据访问
• 只读数据访问不要使用DataSet
• 关闭ASP.NET的Debug模式
• 使用ASP.Net Output Cache缓冲数据
• 尽量用SQL返回DataGrid需要绑定的DataSet,尽量不
要对DataSet进行二次加工,特别不要对DataSet进
行大量删除,实践证明这很慢。不如复制部分数据。
• 尽量把查询数据的数据库操作次数压缩到最少,尽量
1-2次数据库操作就可完成;
• 注意优化数据库查询操作
• 不要在页面加载时默认选择全部数据,尽管可以方便
后续操作,但用户会以为“还没有操作就这么慢”
• 建议尽量用比较高效的SQL代替后续复杂的DataSet
二次加工
• 仅在需要的时候打开数据库连接
• 一旦数据库操作完毕,一定关闭连接
• 在关闭连接时记得删除临时对象
• 在关闭连接前,确保关闭任何用户定义事务
• 显示非交互性数据,使用SQLDataReader可以获得
最佳性能
• 注意共享那些经过复杂处理或漫长查询才得到的数据
• 在页面跳转时记得终止当前页面的处理
• 有大量连接的字符串操作不要使用+,改用
StringBuilder

 

 

 

 

css放在网页的开头,
js放在网页的结尾,
csshejs尽量独立成文件,不要在页面中写css和js
减少不必要的数据库查询,优化程序算法,

 

不管是网站还是管理系统,基本的都是数据库,数据库的瓶颈还是最要命的要害。
数据库:
    放弃关系数据库教科书式(3NF)的设计,多对多关系放弃中间的关系表;
    放弃存储过程,全部使用Sql语句;
    数据库按照业务或者自定义方式划分,有条件可以做散列或者集群等;
    不要开数据库分布式事务;
    数据库结构要优化,使用索引等,记住2-8原则;
    除了主键和索引,尽量不要使用别的数据对象,特别是外键,在不使用proc的情况下,可以少量使用触发器
    有条件可以做数据库的读写分开;
Web:
    能使用静态页面就用静态页面,动态页面可以生成静态页面;
    禁用或者压缩ViewState;
    图片、flash等静态对象尽量不放在网站的目录下,有条件可以单独成服务器;
    有条件可以选择Web集群,尽量使用分布式架构;
    使用缓存,但是需要需要内存安全和数据库实时性,缓存最好使用分布式;
    能用javascript就使用javascript,减少和服务器的往返次数,也减少程序和数据库的往返次数;
    有条件可以选择展现层和业务层分开部署,通常可以使用Web+Remoting(NFW1.1),Web+WCF(》NFW2.0);
    还有一些代码的技巧,这就太多了,这边不说了;

posted @ 2009-05-06 15:48  supers  阅读(207)  评论(0)    收藏  举报