Asp.net程序性能優化詳解

Asp.net程序性能優化詳解

一、性能參數:

1、吞吐量

2、響應時間

3、執行時間

4、可伸縮性

二、性能因素:

1ASPX執行環境

2、編寫代碼邏輯

三、提高性能的方法:

1、避免不必要的操作.例如:Page_Load中使用IsPostBack;

2、儘量減少使用服務器端控件

3、關閉不必要的頁面Session和控件的ViewState <%@Page EnableSessionState =false%>

4、禁用VBJSP動態類型   <%@Page Language=VB Strict=true%>

5、使用存儲過程

6、使用DateReader代替DataSet

7、關閉ASP.NetDebug模式

8、使用ASP.NetOutput Cache緩衝

<%@ OutputCache Duration=60 VaryByParam=”None” %>

<%@ OutputCache Duration=60 VaryByParam=”TextBox1,TextBox2” %>

說明: Duration是設置Cache的過期時間;

     VarByParam是設置是否根據參數而變化,None時所有參數使用同一Cache,設置TextBox1時則根據TextBox1的不同值分別緩存;當有多個參數時則要組合緩存;

9、不要使用Exception控制程序流程

try

{

       result=100/num;

}

catch(Exception e)

{

       result=0;

}

if(num!=0)

       result = 100/num;

else

       result=0;

四、緩衝分類:

1頁面緩衝:根據VarByParam來進行不同的緩衝處理。

2片段緩衝:在頁面控件中使用頁面緩衝,當一個頁面裏多次使用同一個頁面控件時,需要根據VarByControl來進行不同的緩衝處理。

3數據緩衝:Cache(範圍是和Application一樣,所有用戶)

Cache.Insert(“MyData”,Source,null,new CacheDependency(Server.MapPath(“authors.xml”)));

Cache.Insert(“MyData”,Source,null,DateTime.Now.AddHours(1),TimeSpan.Zero);

Cache.Insert(“MyData”,Source,null,DateTime.MaxValue,TimeSpan.FromMinutes(20));

衡量Web性能的方法

l         衡量web服務器性能的唯一方式是對服務器進行壓力測試(stress testing)

1.        自動壓力測試工具是衡量的唯一方式

2.        瀏覽器的點擊刷新並不能作爲痕量手段……

l         收集多個典型應用場景方案:

1.        在應用車工女婿執行過程中模擬典型事物處理的過程

2.        痕量常用的單個頁面的性能(熱點)

3.        確定個場景及個頁面的使用率

l         通過測試找出系統的新能指標:

1.        服務器的處理能力

2.        確定適合可接受TTFB/TTLB響應時間範圍的可支持的最大客戶端負載(併發用戶)

性能測試工具

l         微軟Web Application Stress Tool

1.        可免費下載(10MB),適用於XP、2000、2003

2.        http://www.microsoft.com/technet/treeview/default.aspx?url=/technet/itsolutions/intranet/downloads/webstres.asp

l         微軟應用程序中心測試工具(Microsoft Application Center Test)

1.        作爲VS.NET Enterprise 的一部分提供給客戶

2.        啓用更豐富的腳本及報告

主要的性能測試觀測項PerfMon Counters

l         Processor,CPU % Utilization

Low numbers = blocking or lock contention

l         ASP.NET,Requests In Application Queue

出現線型增長時表示服務器已達滿負荷

l         ASP.NET,Applications,Requests/Sec

動態吞吐量(應保持一致、無大的波動)

l         ASP.NET,Applications,Errors Total

預示着功能級錯誤(應爲0)

l         ASP.NET App/Worker Process Restarts

表示有嚴重錯誤編程級錯誤(應爲0)

壓力測試環境的注意事項

l         在獨立與Web服務器及應用服務器的機器上運行壓力測試工具

1.        否則工具將超出服務器CPU的最大範圍

2.        對於繁重的負載使用多個客戶端機器

提高Asp.Net應用程序的十大方法

譯完了提高Asp.Net應用程序的十大方法這篇文章,仔細想其中提到的每一條,在這裏結合我的項目來談談.

第一條:返回多個結果集

因爲我的項目中所有對數據庫的訪問的sql語句都是通過調用存儲過程實現的,所以基本上都是用一個存儲過程完成返回多個結果集,來得到自己想要的數據.滿足!!

第二條:對數據進行分頁

我寫了一個通用的分頁存儲過程,用於對顯示的數據進行分頁,參照了原來Dino Esposito 的分頁思想寫的,寫成了一篇項目總結髮表在CSDN.經過幾個項目後,發現分頁的效率取決於用於分頁的條件,一般情況下,用索引字段的來作條件分頁的效率是最高的,所以在以後的項目中,要注意分頁的效率.查了一下csdn中的分頁存儲過程,"風雲"的那個分頁存儲過程比較通用,而且效率也高.決定以後用它的那個了.

網址:http://community.csdn.net/Expert/topic/3587/3587201.xml?temp=.6331598

CREATE PROCEDURE sp_page

@tb

  varchar(50), --表名

@col

  varchar(50), --按該列來進行分頁

@coltype

int,

   --@col列的類型,0-數字類型,1-字符類型,2-日期時間類型

@orderby

bit,

   --排序,0-順序,1-倒序

@collist

varchar(800),--要查詢出的字段列表,*表示全部字段

@pagesize   int,

  --每頁記錄數

@page

int,

   --指定頁

@condition  varchar(800),--查詢條件

@pages

int OUTPUT   --總頁數

AS

/*

功能描述:對指定表中滿足條件的記錄按指定列進行分頁查詢,分頁可以順序、倒序

查詢可以指定頁大小、指定查詢任意頁、指定輸出字段列表,返回總頁數

*/

DECLARE @sql nvarchar(4000),@where1 varchar(800),@where2 varchar(800)

IF @condition is null or rtrim(@condition)=''

BEGIN--沒有查詢條件

SET @where1=' WHERE '

SET @where2='  '

END

ELSE

BEGIN--有查詢條件

SET @where1=' WHERE ('+@condition+') AND '--本來有條件再加上此條件

SET @where2=' WHERE ('+@condition+') '--原本沒有條件而加上此條件

END

SET @sql='SELECT @pages=CEILING((COUNT(*)+0.0)/'+CAST(@pagesize AS varchar)+

') FROM '+@tb+@where2

EXEC sp_executesql @sql,N'@pages int OUTPUT',@pages OUTPUT--計算總頁數

IF @orderby=0

SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+

' FROM (SELECT">'+@tb+@where1+@col+'>(SELECT MAX('+@col+') '+

' FROM (SELECT TOP '+CAST(@pagesize*(@page-1) AS varchar)+' '+

@col+' FROM '+@tb+@where2+'ORDER BY '+@col+') t) ORDER BY '+@col

ELSE

SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+

' FROM '+@tb+@where1+@col+'<(SELECT MIN('+@col+') '+

' FROM (SELECT TOP '+CAST(@pagesize*(@page-1) AS varchar)+' '+

@col+' FROM '+@tb+@where2+'ORDER BY '+@col+' DESC) t) ORDER BY '+

@col+' DESC'

IF @page=1--第一頁

SET @sql='SELECT TOP '+CAST(@pagesize AS varchar)+' '+@collist+' FROM '+@tb+

@where2+'ORDER BY '+@col+CASE @orderby WHEN 0 THEN '' ELSE ' DESC' END

EXEC(@sql)

GO

第三條:連接池

默認情況下,.NET是使用連接池來管理連接的.所以在項目上注意兩點:一個是以構造一個類,專門用於返回連接字符串或連接對象,這樣要以保證連接字符串是相同的,纔能有效的利用連接池.另一個是用完連接後馬上關閉邊接.

第四,,七條:充分利用Asp.Net中的各種緩存技術(文章的第四,第五,第七個方法都是用了緩存)

原來的項目中,用過一次頁面輸出緩存,但是沒有成功,因爲頁面要提交,所以不能及時響應事件.就把它下掉了.開始以爲是用緩存的問題.通過這篇文章,才知道是自己不知道怎麼用.所以這段時間就在看有關怎麼利用緩存的資料.應該好好的瞭解緩存的用法.這樣,才能更有效的提高應用程序的效率.如果你也想了解緩存的技術,我找到了以下的幾篇文章,它們都在Msdn中文網上:

ASP.NET 緩存:方法和最佳實踐:

http://www.microsoft.com/china/MSDN/library/WebServices/ASP.NET/ASP.NETCaching-TechniquesandBestPractiCEs.mspx

ASP.NET 中支持數據庫緩存相關性:

http://www.microsoft.com/china/msdn/library/webservices/asp.net/DbCacheDepASPNET.mspx

使用緩存,節省資金:

http://www.microsoft.com/china/msdn/library/webservices/asp.net/aspnetasp11022004.mspx

ASP.NET 創建緩存配置對象:

http://www.microsoft.com/china/MSDN/library/WebServices/ASP.NET/CreatingaCacheConfigurationObjectforASPNET.mspx

還有一本微軟的藍皮書:

Improving .NET Application Performance and Scalability

應該說這一本書是最全,最好的指南了.第六章有一節專門講緩存及緩存應用指南的.正在看這一章.

第六條:在後臺處理

這是我接觸到的一個新的解決方案,原來asp.net中也可以作後臺的定時觸發功能.以後肯定能用上.上面列出的

使用緩存,節省資金:

http://www.microsoft.com/china/msdn/library/webservices/asp.net/aspnetasp11022004.mspx

這篇文章就使用了這一種技術,很有參考價值.

第八,九條:IIS6的新功能

原來一直沒有注意IIS6,都是用IIS5,看來服務器應該升級了.

第十條:有條件的使用ViewState

一直都沒注意ViewState,看來以後只要沒有必須使用ViewState的時候就要把它關掉,特別是用到了DataGrid的頁面.

總的看來,其中用Cache能更好的提高應用程序的性能,如果用到數據庫,記得要充分利用連接池,高效率的分頁;如果用的是windows 2003就不要忘了開它的Kernel Caching.最後也不要忘了關不用ViewState的頁面或控件的EnableViewState屬性.

優化經典:

一、SqlDataReadDataset的選擇

  Sqldataread優點:讀取數據非常快。如果對返回的數據不需做大量處理的情況下,建議使用SqlDataReader,其性能要比datset好很多。缺點:直到數據讀完纔可close掉於數據庫的連接

  (SqlDataReader 讀數據是快速向前的。SqlDataReader 類提供了一種讀取從 SQL Server 數據庫檢索的只進數據流的方法。它使用 SQL Server 的本機網絡數據傳輸格式從數據庫連接直接讀取數據。DataReader需及時顯式的close。可及時的釋放對數據的連接。)

  Dataset是把數據讀出,緩存在內存中。缺點:對內存的佔用較高。如果對返回的數據需做大量的處理用Dataset比較好些可以減少對數據庫的連接操作。優點:只需連接一次就可close於數據庫的連接

  *一般情況下,讀取大量數據,對返回數據不做大量處理用SqlDataReader.對返回數據大量處理用datset比較合適.SqlDataReaderDataset的選擇取決於程序功能的實現。

  二、ExecuteNonQueryExecuteScalar

  對數據的更新不需要返回結果集,建議使用ExecuteNonQuery。由於不返回結果集可省掉網絡數據傳輸。它僅僅返回受影響的行數。如果只需更新數據用ExecuteNonQuery性能的開銷比較小。

  ExecuteScalar它只返回結果集中第一行的第一列。使用 ExecuteScalar 方法從數據庫中檢索單個值(例如id號)。與使用 ExecuteReader 方法,返回的數據執行生成單個值所需的操作相比,此操作需要的代碼較少。

  *只需更新數據用ExecuteNonQuery.單個值的查詢使用ExecuteScalar數據綁定的選擇

  三、數據的綁定DataBinder

  一般的綁定方法<%# DataBinder.Eval(Container.DataItem, "字段名") %>DataBinder.eval 綁定不必關心數據來源(Datareaddataset)。不必關心數據的類型eval會把這個數據對象轉換爲一個字符串。在底層綁定做了很多工作,使用了反射性能。正因爲使用方便了,但卻影響了數據性能。來看下<%# DataBinder.Eval(Container.DataItem, "字段名") %>。當於dataset綁定時,DataItem其實式一個DataRowView(如果綁定的是一個數據讀取器(dataread)它就是一個IdataRecord。)因此直接轉換成DataRowView的話,將會給性能帶來很大提升。

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

  *對數據的綁定建議使用<%# ctype(Container.DataItem,DataRowView).Row("字段名") %>。數據量大的時候可提高几百倍的速度。使用時注意2方面:1.需在頁面添加<%@ Import namespace="System.Data"%>.2.注意字段名的大小寫(要特別注意)。如果和查詢的不一致,在某些情況下會導致比<%# DataBinder.Eval(Container.DataItem, "字段名") %>還要慢。如果想進一步提高速度,可採用<%# ctype(Container.DataItem,DataRowView).Row(0) %>的方法。不過其可讀性不高。

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

  對查看頁面每個執行過程狀態最簡單的辦法:其頁面的trace屬性爲true就可查看細節。

  一、使用存儲過程:

  1、性能方面:存儲過程提供了許多標準sql語言中所沒有的高級特性。其傳遞參數和執行邏輯表達式的功能,有助於應用程序設計者處理複雜任務。另外,存儲過程存儲在本地服務器上,減少了執行該過程所需的網絡傳輸寬帶和執行時間。(存儲過程已經對sql語句進行了預編譯,所以其執行速度比在程序裏執行sql語句快很多)

  2、程序結構方面:從程序的可擴展性看,使用存儲過程會對程序以後的修改帶來方便。比如數據庫的結構改變了,只需修改相對應的存儲結構,和程序中的調用部分即可。這部分不屬於本文探討範圍,屬於程序結構設計方面。所以不在此展開。

  3、程序安全性:使用存儲過程可避免SQL Injection攻擊。

  二、查詢語句的優化(針對sql server2000

  很多人只爲目的寫出sql語句,而不考慮sql語句的執行效率。在這我只提供一優化表順序的方法,(sql語句的優化和原則將會在我的sql server2000學習筆記中專題討論)

  對sql語句執行效率可用sql server2000的查詢分析器來查看語句的執行過程。

  優化表順序:一般情況下,sqlserver 會對錶的連接作出自動優化。例如:select name,no from A join B on A. id=B.id join C on C.id=A.id where name=wang

  儘管A表在From中先列出,然後纔是B,最後纔是C。但sql server可能會首先使用c表。它的選擇原則是相對於該查詢限制爲單行或少數幾行,就可以減少在其他表中查找的總數據量。絕大多數情況下,sql server 會作出最優的選擇,但如果你發覺某個複雜的聯結查詢速度比預計的要慢,就可以使用SET FORCEPLAN語句強制sql server按照表出現順序使用表。如上例加上:SET FORCEPLAN ON…….SET FORCEPLAN OFF 表的執行順序將會按照你所寫的順序執行。在查詢分析器中查看2種執行效率,從而選擇表的連接順序。

  *使用SET FORCEPLAN選擇表聯結順序

  三、頁面的優化(.aspx

  主要針對幾個頁面屬性

  1EnableViewState(頁面的視圖狀態)。如果無特殊要求設置爲false。使用ViewState ,每個對象都必須先序列化到 ViewState 中,然後再通過回傳進行反序列化,因此使用 ViewState是沒有代價的。儘量減少使用對象,如果可能,儘量減少放入 ViewState 中的對象的數目。下面情況基本上可以禁用viewstate

  (1)頁面控件(.ascx

  (2)頁面不回傳給自身。

  (3)無需對控件的事件處理。

  (4)控件沒有動態的或數據綁定的屬性值(或對於每個postpack都在代碼中處理)

  單個頁面或每個頁面都禁用 ViewState,如下所示:單個頁面:<%@ Page EnableViewState="False" %> 每個頁面:在 web.config <Pages EnableViewState="false" /> EnableSessionState保持默認值即可(如果頁面用到sessionstate它纔會佔用資源)。EnableViewStateMac如果無安全上的特殊要求,保持默認值。

  2Pagelayout.頁面佈局模型。建議使用Flowlayout(元素不帶絕對定位屬性添加).Gridlayout(絕對定位屬性)由於採用絕對定位,將會比Flowlayout生產更多的代碼,主要是控件的定位信息。

  3、項目發佈的時候切記解除頁面的Debug狀態。

  4Html語言的優化。我的建議是熟練掌握Html/JavaScript,少用vs.net2003自動生產的代碼,它會自動生成一些無用的html代碼。

  5smart navigation設置爲true能讓用戶明顯的感覺性能提高。啓用此屬性後對客戶端和服務端影響不大.它能智能涮新需要涮新需涮新的部分.

  四、控件的選擇:

  Html控件和服務器控件的選擇。服務器控件帶來的方便和功能上的實現是html控件所不能比擬的。但是是以犧牲服務器端的資源來取得的。我個人建議:如果html控件達不到所要實現的功能,而且和一些腳本語言(如javascrpt/vbscript)結合也不能實現的話。纔會選擇服務器控件。選擇服務器控件後,也儘量對其控件優化,如取消一些頁面狀態等(具體看控件的優化)

  服務器控件的選擇:主要針對幾個常用數據控件說明一下:

  DataGrid:自帶最強大的數據顯示控件,內置了對數據的修改、刪除、添加、分頁等很多實用功能。如果你只需對數據顯示的話,儘量不要選擇DataGrid(它把數據都存儲在viewstate中).也不要使用自帶的分頁功能,microsoft在自動分頁的底層做了很多工作,雖然使用方便了,但性能開銷大了。

  DataList:比DataGrid功能少了很多。但自定義性強了很多。特有的多行數據顯示,給我們帶來了很多方便。DataGrid能實現的功能,它基本能實現。所以建議使用它。

  Repeater:功能最少,但自定義性非常強。如果只需對數據顯示,建議使用。由於減少了很多功能,對服務器的性能帶來消耗最小。因此,如果是對數據顯示的話,我基本上都是選擇Repeater然後DataList最後DataGrid

  *儘量選擇html控件。能在客戶端實現的功能就在客戶端實現(熟練掌握javascript),減少服務器的壓力。數據控件選擇順序:RepeaterDataListDataGrid

  五、服務器控件的優化:

  1Viewstate

  控件的viewstate與頁面的viewstate基本是一致的。用來保存控件的一些狀態。處理原則和處理頁面的viewstate一樣。有興趣的可以用Datagrid綁定數據測試下viewstate保存的數據量有多大,它所保存的數據基本和Datagrid顯示的數據量大小是等同的。

  2Ispostpack

  默認false.需要產生事件的時候才需設置爲true.

  控件的優化,主要看你對此控件的熟悉情況。對控件內部運作的原理越瞭解,就會對其作出合適的優化。

性能優化是三兩句話說不清的,我所寫出的僅僅是冰山一角,性能的優化是靠平時經驗的積累和對程序的運作原理的不斷認知。

ASP.NET中常用的優化性能方法

1. 數據庫訪問性能優化

  數據庫的連接和關閉

  訪問數據庫資源需要創建連接、打開連接和關閉連接幾個操作。這些過程需要多次與數據庫交換信息以通過身份驗證,比較耗費服務器資源。ASP.NET中提供了連接池(Connection Pool)改善打開和關閉數據庫對性能的影響。系統將用戶的數據庫連接放在連接池中,需要時取出,關閉時收回連接,等待下一次的連接請求。

  連接池的大小是有限的,如果在連接池達到最大限度後仍要求創建連接,必然大大影響性能。因此,在建立數據庫連接後只有在真正需要操作時纔打開連接,使用完畢後馬上關閉,從而儘量減少數據庫連接打開的時間,避免出現超出連接限制的情況。

  使用存儲過程

  存儲過程是存儲在服務器上的一組預編譯的SQL語句,類似於DOS系統中的批處理文件。存儲過程具有對數據庫立即訪問的功能,信息處理極爲迅速。使用存儲過程可以避免對命令的多次編譯,在執行一次後其執行規劃就駐留在高速緩存中,以後需要時只需直接調用緩存中的二進制代碼即可。

  另外,存儲過程在服務器端運行,獨立於ASP.NET程序,便於修改,最重要的是它可以減少數據庫操作語句在網絡中的傳輸。

  優化查詢語句

  ASP.NETADO連接消耗的資源相當大,SQL語句運行的時間越長,佔用系統資源的時間也越長。因此,儘量使用優化過的SQL語句以減少執行時間。比如,不在查詢語句中包含子查詢語句,充分利用索引等。

2. 字符串操作性能優化

  使用值類型的ToString方法

  在連接字符串時,經常使用"+"號直接將數字添加到字符串中。這種方法雖然簡單,也可以得到正確結果,但是由於涉及到不同的數據類型,數字需要通過裝箱操作轉化爲引用類型纔可以添加到字符串中。但是裝箱操作對性能影響較大,因爲在進行這類處理時,將在託管堆中分配一個新的對象,原有的值複製到新創建的對象中。

  使用值類型的ToString方法可以避免裝箱操作,從而提高應用程序性能。

  運用StringBuilder

  String類對象是不可改變的,對於String對象的重新賦值在本質上是重新創建了一個String對象並將新值賦予該對象,其方法ToString對性能的提高並非很顯著。

  在處理字符串時,最好使用StringBuilder類,其.NET 命名空間是System.Text。該類並非創建新的對象,而是通過AppendRemoveInsert等方法直接對字符串進行操作,通過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 BasicVBScript 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.exeC# 編譯器)或 vbc.exeVisual 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應用程序時注意性能問題,養成良好的習慣,提高應用程序性能,至少可以推遲必需的硬件升級,降低網站的成本。

常用Asp.NET程序優化方法

版權:待定點擊次數:63


ASP.NET 的緩存機制相比ASP有很大的改進,本文檔除對常用優化方法進行總結介紹外,強調了如何使用ASP.NET的緩存來獲得最佳性能。

1
:不要使用不必要的session
ASP中一樣,在不必要的時候不要使用Session


可以針對整個應用程序或者頁面禁用會話狀態:

l        
禁用頁面的會話狀態


l        
禁用應用程序的會話狀態

在應用程序的Web.Config文件的sessionstate配置節中,將mode屬性設置爲off

即:。



2
:不使用不必要的Server Control
ASP.net
中,大量的服務器端控件方便了程序開發,但也可能帶來性能的損失,因爲用戶每操作一次服務器端控件,就產生一次與服務器端的往返過程。因此,非必要,應當少使用Server Control




3
:不使用不必要的ViewState
默認情況下,ASP.Net對所有的Server Control都啓用了ViewState(視圖狀態)。但ViewState需要在客戶端保存一些信息,這會造成性能的消耗。當必須使用Server Control時,可以考慮禁止ViewState


有兩種方式禁止ViewState:針對整個頁面或者單個控件禁用ViewState

l        
針對控件


l        
針對頁面


4
:不要用Exception控制程序流程
有些程序員可能會使用異常來實現一些流程控制。例如:



try{

   result=100/num;

}

Catch(Exception e)

{

   result=0;

}

但實際上,Exception是非常消耗系統性能的。除非必要,不應當使用異常控制來實現程序流程。

上面的代碼應當寫爲:



if(num!=0)

   result=100/num;

else

   result=0;

5
:禁用VBJscript動態數據類型
應當始終顯示地申明變量數據類型,這能夠節約程序的執行時間。爲此,可以在頁面前面寫明:

6
:使用存儲過程完成數據訪問
7
:只讀數據訪問不要使用DataSet
DataSet
作爲一個功能強大的、支持離線的數據庫,其對性能的開銷也相對較大。在特定的場合可以使用.Net中的其它數據集作爲替代。

n        
使用SqlDataReader代替DataSet

n         SqlDataReader
read-onlyforward-only

8
:關閉ASP.NETDebug模式
爲了方便開發調試,VS.net中對於Debug模式默認是開啓的,在部署應用程序時,應該關閉Debug模式,這將有效提高應用程序性能。

9
:使用ASP.Net Output Cache緩衝數據;
提供緩衝功能是ASP.net中非常強大的一種功能。曾看到過某些評測說:ASP.net程序的性能比SUNJSP應用程序性能快上幾倍,實際上,該評測程序非常重要的一點就是使用了很多ASP.net的緩衝功能。

ASP.net
中常用的緩衝方式有:

n        
頁面緩衝

一個例子:查詢北京市的天氣。因爲天氣數據在一定的時間內是相對規定的。

Web程序中第一次查詢北京市的天氣時,應用程序可能是調用一個遠程的WebService獲取天氣信息。而其後的用戶就可以從緩衝中得到當前的天氣信息。這將大大提高性能,減少服務器的壓力。

方式:

u      
:指明頁面使用緩衝

u       Duration
:控制緩衝有效的時間,單位爲分鐘。

u       VaryByParam
:用於指明是否緩衝的判斷依據。例如,如果第一個用戶查詢的是北京的天氣,則緩衝中存儲了北京市的天氣。當第二個用戶查詢上海的天氣時,爲避免讀取到錯誤的緩衝,可以用這樣的代碼緩衝多個城市的天氣:


這就指明瞭根據頁面URL中的cityName參數來緩衝多份數據。

n        
片斷緩衝

ASP.net中,除了在頁面範圍內使用緩衝,也還可以針對User Control使用Output Cache參數實現對用戶控件的緩衝。同樣的,一個頁面中相同類型的控件也可以有多個不同的緩衝。可以根據參數來實現不同的緩衝。

例如:對於控件可以根據Control C屬性的不同實現不同的緩衝。



n        
數據緩衝



n        
緩衝的過期依賴條件

某種意義上,CacheApplication是一樣的,都是一種公有的對象。爲了取得緩衝與數據有效性之間的平衡,可以根據需要對緩衝過期策略進行合理的設置。

u      
文件依賴

Cache.Insert (“Mydata”, Source

                           , New CacheDependency(Server.MapPath(“authors.xml”)))

此代碼的含義是當authors.xml文件不發生變化的時候,緩衝MyData始終有效。



u      
時間依賴

設定1小時後過期,這是一種絕對過期。

Cache.Insert(“Mydata”,Source,null

                          ,DateTime.Now.AddHours(1),TimeSpan.Zero);



u      
相對過期依賴

DataSet不再發生變化20分鐘以後,緩衝過期。

Cache.Insert(“MyData”,Source,null

                        ,DateTime.MaxValue,TimeSpan.FromMinutes(20));

Asp.net性能優化總結

一、使用存儲過程:

1.  性能方面:存儲過程提供了許多標準sql語言中所沒有的高級特性。其傳遞參數和執行邏輯表達式的功能,有助於應用程序設計者處理複雜任務。另外,存儲過程存儲在本地服務器上,減少了執行該過程所需的網絡傳輸寬帶和執行時間。(存儲過程已經對sql語句進行了預編譯,所以其執行速度比在程序裏執行sql語句快很多)

2.  程序結構方面:從程序的可擴展性看,使用存儲過程會對程序以後的修改帶來方便。比如數據庫的結構改變了,只需修改相對應的存儲結構,和程序中的調用部分即可。

這部分不屬於本文探討範圍,屬於程序結構設計方面。所以不在此展開。

3.  程序安全性:使用存儲過程可避免SQL Injection攻擊。

二、查詢語句的優化(針對sql server2000

很多人只爲目的寫出sql語句,而不考慮sql語句的執行效率。在這我只提供一優化表順序的方法,(sql語句的優化和原則將會在我的sql server2000學習筆記中專題討論)

sql語句執行效率可用sql server2000的查詢分析器來查看語句的執行過程。

優化表順序:一般情況下,sqlserver 會對錶的連接作出自動優化。例如:

select name,no from A

join B on A. id=B.id

join C on C.id=A.id

where name=’wang’

儘管A表在From中先列出,然後纔是B,最後纔是C。但sql server可能會首先使用c表。它的選擇原則是相對於該查詢限制爲單行或少數幾行,就可以減少在其他表中查找的總數據量。絕大多數情況下,sql server 會作出最優的選擇,但如果你發覺某個複雜的聯結查詢速度比預計的要慢,就可以使用SET FORCEPLAN語句強制sql server按照表出現順序使用表。如上例加上:SET FORCEPLAN ON…….SET FORCEPLAN OFF  表的執行順序將會按照你所寫的順序執行。在查詢分析器中查看2種執行效率,從而選擇表的連接順序。

*使用SET FORCEPLAN選擇表聯結順序

三、頁面的優化(.aspx

主要針對幾個頁面屬性

1.EnableViewState(頁面的視圖狀態)。如果無特殊要求設置爲false

使用ViewState ,每個對象都必須先序列化到 ViewState 中,然後再通過回傳進行反序列化,因此使用 ViewState是沒有代價的。儘量減少使用對象,如果可能,儘量減少放入 ViewState 中的對象的數目。下面情況基本上可以禁用viewstate

1)頁面控件.ascx

2)頁面不回傳給自身。

3)無需對控件的事件處理。

4)控件沒有動態的或數據綁定的屬性值(或對於每個postpack都在代碼中處理)

單個頁面或每個頁面都禁用 ViewState,如下所示:

單個頁面:<%@ Page EnableViewState="False" %>

每個頁面:在 web.config <Pages EnableViewState="false" />

EnableSessionState保持默認值即可(如果頁面用到sessionstate它纔會佔用資源)。

EnableViewStateMac如果無安全上的特殊要求,保持默認值。

2.Pagelayout.頁面佈局模型。建議使用Flowlayout(元素不帶絕對定位屬性添加).Gridlayout(絕對定位屬性)由於採用絕對定位,將會比Flowlayout生產更多的代碼,主要是控件的定位信息。

3.項目發佈的時候切記解除頁面的Debug狀態。

4Html語言的優化。我的建議是熟練掌握Html/JavaScript,少用vs.net2003自動生產的代碼,它會自動生成一些無用的html代碼。

5. smart navigation設置爲true能讓用戶明顯的感覺性能提高。啓用此屬性後對客戶端和服務端影響不大.它能智能涮新需要涮新需涮新的部分.

四、控件的選擇:

Html控件和服務器控件的選擇。服務器控件帶來的方便和功能上的實現是html控件所不能比擬的。但是是以犧牲服務器端的資源來取得的。我個人建議:如果html控件達不到所要實現的功能,而且和一些腳本語言(如javascrpt/vbscript)結合也不能實現的話。纔會選擇服務器控件。選擇服務器控件後,也儘量對其控件優化,如取消一些頁面狀態等(具體看控件的優化)

服務器控件的選擇:主要針對幾個常用數據控件說明一下:

DataGrid:自帶最強大的數據顯示控件,內置了對數據的修改、刪除、添加、分頁等很多實用功能。如果你只需對數據顯示的話,儘量不要選擇DataGrid(它把數據都存儲在viewstate中).也不要使用自帶的分頁功能,microsoft在自動分頁的底層做了很多工作,雖然使用方便了,但性能開銷大了。(推薦一分頁控件:http://webdiyer.europe.webmatrixhosting.net/default.aspx

   DataList:比DataGrid功能少了很多。但自定義性強了很多。特有的多行數據顯示,給我們帶來了很多方便。DataGrid能實現的功能,它基本能實現。所以建議使用它。

   Repeater:功能最少,但自定義性非常強。如果只需對數據顯示,建議使用。由於減少了很多功能,對服務器的性能帶來消耗最小。因此,如果是對數據顯示的話,我基本上都是選擇Repeater然後DataList最後DataGrid

*儘量選擇html控件。能在客戶端實現的功能就在客戶端實現(熟練掌握javascript),減少服務器的壓力。數據控件選擇順序:RepeaterDataListDataGrid

五、服務器控件的優化:

1.Viewstate

控件的viewstate與頁面的viewstate基本是一致的。用來保存控件的一些狀態。

處理原則和處理頁面的viewstate一樣。有興趣的可以用Datagrid綁定數據測試下

viewstate保存的數據量有多大,它所保存的數據基本和Datagrid顯示的數據量大小

是等同的。

2.Ispostpack

默認false.需要產生事件的時候才需設置爲true.

控件的優化,主要看你對此控件的熟悉情況。對控件內部運作的原理越瞭解,就會對其作出合適的優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章