aspnet程序性能優(yōu)化的七個方面_第1頁
aspnet程序性能優(yōu)化的七個方面_第2頁
aspnet程序性能優(yōu)化的七個方面_第3頁
aspnet程序性能優(yōu)化的七個方面_第4頁
aspnet程序性能優(yōu)化的七個方面_第5頁
已閱讀5頁,還剩21頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、asp net程序性能優(yōu)化的七個方面一、數(shù)據(jù)庫操作1、用完馬上關(guān)閉數(shù)據(jù)庫連接訪問數(shù)據(jù)庫資源需要創(chuàng)建連接、打開連接和關(guān)閉連接幾個操作。這些過程需要多次與數(shù)據(jù)庫交換信息以通過身份驗(yàn)證,比較耗費(fèi)服務(wù)器資源。ASP.NET中提供了連接池(Connection Pool)改善打開和關(guān)閉數(shù)據(jù)庫對性能的影響。系統(tǒng)將用戶的數(shù)據(jù)庫連接放在連接池中,需要時取出,關(guān)閉時收回連接,等待下一次的連接請求。連接池的大小是有限的,如果在連接池達(dá)到最大限度后仍要求創(chuàng)建連接,必然大大影響性能。因此,在建立數(shù)據(jù)庫連接后只有在真正需要操作時才打開連接,使用完畢后馬上關(guān)閉,從而盡量減少數(shù)據(jù)庫連接打開的時間,避免出現(xiàn)超出連接限制的情況

2、。用(推薦)using(SqlConnection Conn=new SqlConnection(connstr)/不必顯示關(guān)閉或tryconn.Open();catchfinallyconn.Close();2、盡量使用存儲過程,并優(yōu)化查詢語句存儲過程是存儲在服務(wù)器上的一組預(yù)編譯的SQL語句,類似于DOS系統(tǒng)中的批處理文件。存儲過程具有對數(shù)據(jù)庫立即訪問的功能,信息處理極為迅速。使用存儲過程可以避免對命令的多次編譯,在執(zhí)行一次后其執(zhí)行規(guī)劃就駐留在高速緩存中,以后需要時只需直接調(diào)用緩存中的二進(jìn)制代碼即可。在.NET Framework提供的所有數(shù)據(jù)訪問方法中,基于SQL Server的數(shù)據(jù)訪問是

3、生成高性能、可縮放Web應(yīng)用程序的推薦選擇。使用托管SQL Server提供程序時,可通過使用編譯的存儲過程而不是特殊查詢獲得額外的性能提高。另外,存儲過程在服務(wù)器端運(yùn)行,獨(dú)立于ASP.NET程序,便于修改,最重要的是它可以減少數(shù)據(jù)庫操作語句在網(wǎng)絡(luò)中的傳輸。優(yōu)化查詢語句ASP.NET中ADO連接消耗的資源相當(dāng)大,SQL語句運(yùn)行的時間越長,占用系統(tǒng)資源的時間也越長。因此,盡量使用優(yōu)化過的SQL語句以減少執(zhí)行時間。比如,不在查詢語句中包含子查詢語句,盡量只返回有用的數(shù)據(jù)、字段,充分利用索引等。3、只讀數(shù)據(jù)訪問用SqlDataReader,不要使用DataSet SqlDataReader類提供了一

4、種讀取從SQL Server數(shù)據(jù)庫檢索的只進(jìn)數(shù)據(jù)流的方法。如果當(dāng)創(chuàng)建ASP.NET應(yīng)用程序時出現(xiàn)允許您使用它的情況,則SqlDataReader類提供比DataSet類更高的性能。情況之所以這樣,是因?yàn)镾qlDataReader使用SQL Server的本機(jī)網(wǎng)絡(luò)數(shù)據(jù)傳輸格式從數(shù)據(jù)庫連接直接讀取數(shù)據(jù)。另外,SqlDataReader類實(shí)現(xiàn)IEnumerable接口,該接口也允許您將數(shù)據(jù)綁定到服務(wù)器控件。DataSet作為一個功能強(qiáng)大的、支持離線的數(shù)據(jù)庫,其對性能的開銷也相對較大。Sqldataread優(yōu)點(diǎn):讀取數(shù)據(jù)非??臁H绻麑Ψ祷氐臄?shù)據(jù)不需做大量處理的情況下,建議使用SqlDataReader

5、,其性能要比datset好很多。缺點(diǎn):直到數(shù)據(jù)讀完才可close掉于數(shù)據(jù)庫的連接。Dataset是把數(shù)據(jù)讀出,緩存在內(nèi)存中。缺點(diǎn):對內(nèi)存的占用較高。如果對返回的數(shù)據(jù)需做大量的處理用Dataset比較好些可以減少對數(shù)據(jù)庫的連接操作。優(yōu)點(diǎn):只需連接一次就可close于數(shù)據(jù)庫的連接。一般情況下,讀取大量數(shù)據(jù),對返回數(shù)據(jù)不做大量處理用SqlDataReader.對返回數(shù)據(jù)大量處理用datset比較合適.對SqlDataReader和Dataset的選擇取決于程序功能的實(shí)現(xiàn)。4、數(shù)據(jù)的綁定DataBinder一般的綁定方法%#DataBinder.Eval(Container.DataItem,字段名)

6、%用DataBinder.eval綁定不必關(guān)心數(shù)據(jù)來源(read或dataset)。不必關(guān)心數(shù)據(jù)的類型eval會把這個數(shù)據(jù)對象轉(zhuǎn)換為一個字符串。在底層綁定做了很多工作,使用了反射性能。正因?yàn)槭褂梅奖懔?,但卻影響了數(shù)據(jù)性能。來看下%#DataBinder.Eval(Container.DataItem,字段名)%。當(dāng)于dataset綁定時,DataItem其實(shí)式一個DataRowView(如果綁定的是一個數(shù)據(jù)讀取器(dataread)它就是一個IdataRecord。)因此直接轉(zhuǎn)換成DataRowView的話,將會給性能帶來很大提升。%#ctype(Container.DataItem,Data

7、RowView).Row(字段名)%對數(shù)據(jù)的綁定建議使用%#ctype(Container.DataItem,DataRowView).Row(字段名)%。使用時注意兩個方面:1.需在頁面添加%Import namespace=System.Data%.2.注意字段名的大小寫(要特別注意)。如果和查詢的不一致,在某些情況下會導(dǎo)致比%#DataBinder.Eval(Container.DataItem,字段名)%還要慢。如果想進(jìn)一步提高速度,可采用%#ctype(Container.DataItem,DataRowView).Row(0)%的方法。不過其可讀性不高。以上的是的寫法。

8、在c#中:%#(DataRowView)Container.DataItem)字段名%5、返回多個結(jié)果集無論SqlDataReader還是datset,返回多個結(jié)果集,然后用rd.NextResult()或ds.Tables來分別處理數(shù)據(jù),減少重復(fù)連接數(shù)據(jù)庫的次數(shù)。同時盡量用比較高效的SQL代替后續(xù)復(fù)雜的DataSet二次加工。二、頁面優(yōu)化1、不使用不必要的服務(wù)器控件(Server Control)ASP.net中,大量的服務(wù)器端控件方便了程序開發(fā),但也可能帶來性能的損失,因?yàn)橛脩裘坎僮饕淮畏?wù)器端控件,就產(chǎn)生一次與服務(wù)器端的往返過程。因此,非必要,應(yīng)當(dāng)少使用Server Control。還有

9、許多其他情況,在這些情況中呈現(xiàn)或數(shù)據(jù)綁定比使用服務(wù)器控件更有效,甚至是在使用服務(wù)器控件模板時。但是,如果要以編程方式操作服務(wù)器控件的屬性、處理服務(wù)器控件事件或利用視圖狀態(tài)保存,則使用服務(wù)器控件是適當(dāng)?shù)?。所以,盡量選擇html控件。能在客戶端實(shí)現(xiàn)的功能就在客戶端實(shí)現(xiàn)(熟練掌握javascript),減少服務(wù)器的壓力。2、不使用不必要的ViewState默認(rèn)情況下,ASP.Net對所有的Server Control都啟用了ViewState(視圖狀態(tài))。但ViewState需要在客戶端保存一些信息,這會造成性能的消耗。當(dāng)必須使用Server Control時,可以考慮禁止ViewState。只在必

10、要時保存服務(wù)器控件視圖狀態(tài)。自動視圖狀態(tài)管理是服務(wù)器控件的功能,該功能使服務(wù)器控件可以在往返過程上重新填充它們的屬性值(您不需要編寫任何代碼)。但是,因?yàn)榉?wù)器控件的視圖狀態(tài)在隱藏的窗體字段中往返于服務(wù)器,所以該功能確實(shí)會對性能產(chǎn)生影響。您應(yīng)該知道在哪些情況下視圖狀態(tài)會有所幫助,在哪些情況下它影響頁的性能。例如,如果您將服務(wù)器控件綁定到每個往返過程上的數(shù)據(jù),則將用從數(shù)據(jù)綁定操作獲得的新值替換保存的視圖狀態(tài)。在這種情況下,禁用視圖狀態(tài)可以節(jié)省處理時間。默認(rèn)情況下,為所有服務(wù)器控件啟用視圖狀態(tài)。若要禁用視圖狀態(tài),請將控件的EnableViewState屬性設(shè)置為false,如下面的DataGrid

11、服務(wù)器控件示例所示。asp:datagrid EnableViewState=falserunat=server/您還可以使用Page指令禁用整個頁的視圖狀態(tài)。當(dāng)您不從頁回發(fā)到服務(wù)器時,這將十分有用:%Page EnableViewState=false%注意Control指令中也支持EnableViewState屬性,該指令允許您控制是否為用戶控件啟用視圖狀態(tài)。若要分析頁上服務(wù)器控件使用的視圖狀態(tài)的數(shù)量,請(通過將trace=true屬性包括在Page指令中)啟用該頁的跟蹤并查看Control Hierarchy表的Viewstate列。3、避免到服務(wù)器的不必要的往返過程雖然您很可能希望盡量

12、多地使用Web窗體頁框架的那些節(jié)省時間和代碼的功能,但在某些情況下卻不宜使用ASP.NET服務(wù)器控件和回發(fā)事件處理。通常,只有在檢索或存儲數(shù)據(jù)時,您才需要啟動到服務(wù)器的往返過程。多數(shù)數(shù)據(jù)操作可在這些往返過程間的客戶端上進(jìn)行。例如,從HTML窗體驗(yàn)證用戶輸入經(jīng)??稍跀?shù)據(jù)提交到服務(wù)器之前在客戶端進(jìn)行。通常,如果不需要將信息傳遞到服務(wù)器以將其存儲在數(shù)據(jù)庫中,那么您不應(yīng)該編寫導(dǎo)致往返過程的代碼。如果您開發(fā)自定義服務(wù)器控件,請考慮讓它們?yōu)橹С諩CMAScript的瀏覽器呈現(xiàn)客戶端代碼。通過以這種方式使用服務(wù)器控件,您可以顯著地減少信息被不必要的發(fā)送到Web服務(wù)器的次數(shù)。使用Page.IsPostBack

13、避免對往返過程執(zhí)行不必要的處理如果您編寫處理服務(wù)器控件回發(fā)處理的代碼,有時可能需要在首次請求頁時執(zhí)行其他代碼,而不是當(dāng)用戶發(fā)送包含在該頁中的HTML窗體時執(zhí)行的代碼。根據(jù)該頁是否是響應(yīng)服務(wù)器控件事件生成的,使用Page.IsPostBack屬性有條件地執(zhí)行代碼。例如,下面的代碼演示如何創(chuàng)建數(shù)據(jù)庫連接和命令,該命令在首次請求該頁時將數(shù)據(jù)綁定到DataGrid服務(wù)器控件。void Page_Load(Object sender,EventArgs e)if(!Page.IsPostBack)由于每次請求時都執(zhí)行Page_Load事件,上述代碼檢查IsPostBack屬性是否設(shè)置為false。如果是

14、,則執(zhí)行代碼。如果該屬性設(shè)置為true,則不執(zhí)行代碼。注意如果不運(yùn)行這種檢查,回發(fā)頁的行為將不更改。Page_Load事件的代碼在執(zhí)行服務(wù)器控件事件之前執(zhí)行,但只有服務(wù)器控件事件的結(jié)果才可能在輸出頁上呈現(xiàn)。如果不運(yùn)行該檢查,仍將為Page_Load事件和該頁上的任何服務(wù)器控件事件執(zhí)行處理。4、當(dāng)不使用會話狀態(tài)時禁用它,并且程序開發(fā)中盡量少用Session并不是所有的應(yīng)用程序或頁都需要針對于具體用戶的會話狀態(tài),您應(yīng)該對任何不需要會話狀態(tài)的應(yīng)用程序或頁禁用會話狀態(tài)。若要禁用頁的會話狀態(tài),請將Page指令中的EnableSessionState屬性設(shè)置為false。例如:%Page EnableSe

15、ssionState=false%注意如果頁需要訪問會話變量,但不打算創(chuàng)建或修改它們,則將Page指令中的EnableSessionState屬性設(shè)置為ReadOnly。若要禁用應(yīng)用程序的會話狀態(tài),請在應(yīng)用程序Web.config文件的sessionstate配置節(jié)中將mode屬性設(shè)置為off。例如:sessionstate mode=off/5、合理使用DataGrid(在2.0中為GridView)控件DataGrid控件帶有最強(qiáng)大的數(shù)據(jù)顯示功能,還內(nèi)置了對數(shù)據(jù)的修改、刪除、添加、分頁等很多功能。如果只需簡單的顯示數(shù)據(jù),DataGrid并非最佳選擇。DataGrid控件的分頁

16、功能,數(shù)據(jù)的存儲方式(存儲在viewstate中)等,雖然讓程序開發(fā)者使用方便快捷,但由此產(chǎn)生的性能開銷不容小視。DataList控件比DataGrid功能少了很多。但自定義性強(qiáng)了很多。特有的多行數(shù)據(jù)顯示還是比較方便的。DataGrid能實(shí)現(xiàn)的功能,它基本能實(shí)現(xiàn)。Repeater控件功能最少,但自定義性非常強(qiáng)。由于減少了很多功能,對服務(wù)器的性能帶來消耗最小。因此,在只需簡單顯示數(shù)據(jù)列表時,選擇Repeater或DataList控件同樣可以達(dá)到目的,而且減輕了性能上的開銷。建議選擇順序:Repeater然后DataList最后DataGrid(GridView)6、對數(shù)據(jù)進(jìn)行分頁ASP.NET的

17、DataGrid(在2.0中為GridView)有一個非常有用的功能:分頁。如果DataGrid允許分頁,在某一時刻它只下載某一頁的數(shù)據(jù),另外,它有一個數(shù)據(jù)分頁的瀏覽導(dǎo)航欄,它讓你可以選擇瀏覽某一頁,而且每次只下載一頁的數(shù)據(jù)。但是它有一個小小的缺點(diǎn),就是你必須把所有的數(shù)據(jù)都綁定到DataGrid中。也就是說,你的數(shù)據(jù)層必須返回所有的數(shù)據(jù),然后DataGrid再根據(jù)當(dāng)前頁過濾出當(dāng)前頁所需要的數(shù)據(jù)顯示出來。如果有一個一萬條記錄的結(jié)果集要用DataGrid進(jìn)行分頁,假設(shè)DataGrid每頁只顯示25條數(shù)據(jù),那就意味著每次請求都有9975條數(shù)據(jù)都是要丟棄的。每次請求都要返回這么大的數(shù)據(jù)集

18、,對應(yīng)用程序的性能影響是非常大的。一個好的解決方案是寫一個分頁的存儲過程,如:CREATE PROCEDURE dbo.sp_DataPagesSql nVARCHAR(2000),PK varchar(50),-主鍵字段名(可以是任何數(shù)據(jù)類型;不能,并且也不需要帶表名前綴,如:不可以是users.id)Order varchar(50),-排序方式(帶desc或asc,可以是多個組合;不能,并且也不需要帶表名前綴,如:不可以是users.id desc)Page int,PageSize int=30 AS set nocount on DECLAREStr nVARCHAR(4000)if

19、(Page=1)SETStr=Select Top+CAST(PageSize)As VARCHAR(20)+*From(+Sql+)As table1 Order By table1.+Order else SETStr=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

20、By table1.+Order-printstr-exec(Str)EXEC sp_ExecuteSqlStr set nocount off GO或者,使用sql server 2005中的row_number()函數(shù)declaresql varchar(8000)setsql=select*+from+(+select row_number()over(order by id desc)as rowNumber,*+from Users+where id 0and name+)+as table1+where rowNumber between+str(page-1)*pagesize+

21、1)+AND+str(page*pagesize)+order by id desc-exec(sql)EXEC sp_ExecuteSqlsql(小技巧:將記錄總數(shù)保為Cache或Session來提高分頁性能。)7、不要禁用Web窗體頁的緩沖除非有特殊的原因要關(guān)閉緩沖,否則使其保持打開。禁用Web窗體頁的緩沖會導(dǎo)致大量的性能開銷。啟用頁面輸出的緩沖區(qū)(Buffer)如果Buffer的機(jī)制被關(guān)閉,可以用下面的方法打開。使用程序打開頁面輸出緩存:Response.BufferOutput=true;使用Page開關(guān)打開頁面輸出緩沖機(jī)制:%Page Buffer=true%使用Web.config

22、或Machine.config配置文件的pages節(jié)點(diǎn):pages buffer=true/8、設(shè)置page的smart navigation屬性smart navigation設(shè)置為true能讓用戶明顯的感覺性能提高。啟用此屬性后對客戶端和服務(wù)端影響不大.它能智能刷新需要刷新的部分。在大多數(shù)情況下不要在代碼中設(shè)置該屬性。在.aspx文件的Page指令中將SmartNavigation屬性設(shè)置為true。請求該頁時,動態(tài)生成的類將設(shè)置該屬性。Internet Explorer 5或更高版本瀏覽器請求頁時(或稍后),智能導(dǎo)航將通過執(zhí)行下列功能提高用戶對該頁的操作能力:消除導(dǎo)航導(dǎo)致的閃爍。從一頁移

23、動到另一頁時保持滾動位置。保持導(dǎo)航之間的元素焦點(diǎn)。在瀏覽器的歷史記錄中只保留最后一頁的狀態(tài)。智能導(dǎo)航最適用于需要頻繁回發(fā),但是其內(nèi)容在返回時不會發(fā)生顯著更改的ASP.NET頁。在決定是否將該屬性設(shè)置為true時,請仔細(xì)考慮這一點(diǎn)。三、c#(或)程序改進(jìn)1、使用值類型的ToString方法在連接字符串時,經(jīng)常使用+號直接將數(shù)字添加到字符串中。這種方法雖然簡單,也可以得到正確結(jié)果,但是由于涉及到不同的數(shù)據(jù)類型,數(shù)字需要通過裝箱操作轉(zhuǎn)化為引用類型才可以添加到字符串中。但是裝箱操作對性能影響較大,因?yàn)樵谶M(jìn)行這類處理時,將在托管堆中分配一個新的對象,原有的值復(fù)制到新創(chuàng)建的對象中。使用值類型的

24、ToString方法可以避免裝箱操作,從而提高應(yīng)用程序性能。int num=1;string str=go+num.ToString();2、運(yùn)用StringBuilder類String類對象是不可改變的,對于String對象的重新賦值在本質(zhì)上是重新創(chuàng)建了一個String對象并將新值賦予該對象,其方法ToString對性能的提高并非很顯著。在處理字符串時,最好使用StringBuilder類,其.NET命名空間是System.Text。該類并非創(chuàng)建新的對象,而是通過Append,Remove,Insert等方法直接對字符串進(jìn)行操作,通過ToString方法返回操作結(jié)果。其定義及操作語句如下所示

25、:int num;System.Text.StringBuilder str=new System.Text.StringBuilder();/創(chuàng)建字符串str.Append(num.ToString();/添加數(shù)值num Response.Write(str.ToString);/顯示操作結(jié)果3、使用HttpServerUtility.Transfer方法在同一應(yīng)用程序的頁面間重定向采用Server.Transfer語法,在頁面中使用該方法可避免不必要的客戶端重定向(Response.Redirect)。4、避免使用ArrayList。因?yàn)槿魏螌ο筇砑拥紸rrayList都要封箱為Syste

26、m.Object類型,從ArrayList取出數(shù)據(jù)時,要拆箱回實(shí)際的類型。建議使用自定義的集合類型代替ArrayL 2.0提供了一個新的類型,叫泛型,這是一個強(qiáng)類型,使用泛型集合就可以避免了封箱和拆箱的發(fā)生,提高了性能。5、使用HashTale代替其他字典集合類型(如StringDictionary,NameValueCollection,HybridCollection),存放少量數(shù)據(jù)的時候可以使用HashTable.6、為字符串容器聲明常量,不要直接把字符封裝在雙引號里面。/避免MyObject obj=new MyObject();obj.Status=ACTIVE

27、;/推薦const string C_STATUS=ACTIVE;MyObject obj=new MyObject();obj.Status=C_STATUS;7、不要用ToUpper(),ToLower()轉(zhuǎn)換字符串進(jìn)行比較,用String.Compare代替,它可以忽略大小寫進(jìn)行比較.例:const string C_VALUE=COMPARE;if(String.Compare(sVariable,C_VALUE,true)=0)Console.Write(相同);也可以用str=String.Empty或者str.Length=0判斷是否為空。(注意判斷輸入數(shù)據(jù)的長度,可防止sql注

28、入式攻擊)將String對象的Length屬性與0比較是最快的方法,避免不必要的調(diào)用ToUpper或ToLower方法。8、類型轉(zhuǎn)化Int32.TryParse()優(yōu)于Int32.Parse()優(yōu)于Convert.ToInt32()。建議.NET1.1下用Int32.Parse();.NET2.0用Int32.TryParse()。因?yàn)椋篊onvert.ToInt32會把最終的解析工作代理給Int32.Parse;Int32.Parse會把最終的解析工作代理給Number.ParseInt32;Int32.TryParse會把最終的解析工作代理給Number.TryParseInt32。9、如

29、果只是從XML對象讀取數(shù)據(jù),用只讀的XPathDocument代替XMLDocument,可以提高性能/避免XmlDocument xmld=new XmlDocument();xmld.LoadXml(sXML);txtName.Text=xmld.SelectSingleNode(/packet/child).InnerText;/推薦XPathDocument xmldContext=new XPathDocument(new StringReader(oContext.Value);XPathNavigator xnav=xmldContext.CreateNavigator();XP

30、athNodeIterator xpNodeIter=xnav.Select(packet/child);iCount=xpNodeIter.Count;xpNodeIter=xnav.SelectDescendants(XPathNodeType.Element,false);while(xpNodeIter.MoveNext()sCurrValues+=xpNodeIter.Current.Value+,;10、避免在循環(huán)體里聲明變量,應(yīng)該在循環(huán)體外聲明變量,在循環(huán)體里初始化。C#程序開發(fā)要遵循的一個基本原則就是避免不必要的對象創(chuàng)建/避免for(int i=0;i 10;i+)SomeCl

31、ass objSC=new SomeClass();/推薦SomeClass objSC=null;for(int i=0;i 10;i+)objSC=new SomeClass();11、捕獲指定的異常,不要使用通用的System.Exception./避免trysome logiccatch(Exception exc)Error handling/推薦trysome logiccatch(System.NullReferenceException exc)Error handlingcatch(System.ArgumentOutOfRangeException exc)Error ha

32、ndlingcatch(System.InvalidCastException exc)Error handling12、使用Try.catch.finally時,要在finally里釋放占用的資源如連接,文件流等不然在Catch到錯誤后占用的資源不能釋放。trycatchfinallyconntion.close();13、不要用Exception控制程序流程有些程序員可能會使用異常來實(shí)現(xiàn)一些流程控制。例如:tryresult=100/num;Catch(Exception e)result=0;但實(shí)際上,Exception是非常消耗系統(tǒng)性能的。除非必要,不應(yīng)當(dāng)使用異??刂苼韺?shí)現(xiàn)程序流程。上

33、面的代碼應(yīng)當(dāng)寫為:if(num!=0)result=100/num;else result=0;14、避免使用遞歸調(diào)用和嵌套循環(huán),使用他們會嚴(yán)重影響性能,在不得不用的時候才使用。15、禁用VB.net和Jscript動態(tài)數(shù)據(jù)類型應(yīng)當(dāng)始終顯示地申明變量數(shù)據(jù)類型,這能夠節(jié)約程序的執(zhí)行時間。以往,開發(fā)人員喜歡使用Visual Basic、VBScript和JScript的原因之一就是它們所謂無類型的性質(zhì)。變量不需要顯式類型聲明,并能夠簡單地通過使用來創(chuàng)建它們。當(dāng)從一個類型到另一個類型進(jìn)行分配時,轉(zhuǎn)換將自動執(zhí)行。不過,這種便利會大大損害應(yīng)用程序的性能。如:為了獲得最佳的性能,當(dāng)聲明JScript.NE

34、T變量時,請為其分配一個類型。例如,var A:String;四、使用緩存1、使用Output Cache緩存數(shù)據(jù)提供緩存功能是ASP.net中非常強(qiáng)大的一種功能。曾看到過某些評測說:ASP.net程序的性能比SUN的JSP應(yīng)用程序性能快上幾倍,實(shí)際上,該評測程序非常重要的一點(diǎn)就是使用了很多ASP.net的緩存功能。如果你的組件是要在A應(yīng)用程序中運(yùn)行,你只要把System.Web.dll引用到你的項目中就可以了。然后用HttpRuntime.Cache屬性就可訪問Cache了(也可以通過Page.Cache或HttpContext.Cache訪問)。有以下幾條緩存數(shù)據(jù)的規(guī)則。第一,

35、數(shù)據(jù)可能會被頻繁的被使用,這種數(shù)據(jù)可以緩存。第二,數(shù)據(jù)的訪問頻率非常高,或者一個數(shù)據(jù)的訪問頻率不高,但是它的生存周期很長,這樣的數(shù)據(jù)最好也緩存起來。第三是一個常常被忽略的問題,有時候我們緩存了太多數(shù)據(jù),通常在一臺X86的機(jī)子上,如果你要緩存的數(shù)據(jù)超過800M的話,就會出現(xiàn)內(nèi)存溢出的錯誤。所以說緩存是有限的。換名話說,你應(yīng)該估計緩存集的大小,把緩存集的大小限制在10以內(nèi),否則它可能會出問題。在A中,如果緩存過大的話也會報內(nèi)存溢出錯誤,特別是如果緩存大的DataSet對象的時候。這里有幾個你必須了解的重要的緩存機(jī)制。首先是緩存實(shí)現(xiàn)了最近使用原則(a least-recently-use

36、d algorithm),當(dāng)緩存少的時候,它會自動的強(qiáng)制清除那些無用的緩存。其次條件依賴強(qiáng)制清除原則(expiration dependencies),條件可以是時間,關(guān)鍵字和文件。以時間作為條件是最常用的。在2.0中增加一更強(qiáng)的條件,就是數(shù)據(jù)庫條件。當(dāng)數(shù)據(jù)庫中的數(shù)據(jù)發(fā)生變化時,就會強(qiáng)制清除緩存。使用ASP.NET緩存機(jī)制有兩點(diǎn)需要注意。首先,不要緩存太多項。緩存每個項均有開銷,特別是在內(nèi)存使用方面。不要緩存容易重新計算和很少使用的項。其次,給緩存的項分配的有效期不要太短。很快到期的項會導(dǎo)致緩存中不必要的周轉(zhuǎn),并且經(jīng)常導(dǎo)致更多的代碼清除和垃圾回收工作。若關(guān)心此問題,請監(jiān)視與ASP

37、.NET Applications性能對象關(guān)聯(lián)的Cache Total Turnover Rate性能計數(shù)器。高周轉(zhuǎn)率可能說明存在問題,特別是當(dāng)項在到期前被移除時。這也稱作內(nèi)存壓力。切記:應(yīng)該:應(yīng)該緩存那些經(jīng)常被訪問、同時變化頻率不大的數(shù)據(jù)應(yīng)該緩存整個應(yīng)用程序都要使用的設(shè)置或?qū)ο?,但這些設(shè)置和對象必須在其生存期內(nèi)不會變化不應(yīng)該:不要緩存?zhèn)€人信息。如果緩存?zhèn)€人信息,其他人很容易取得這些信息。不要緩存包含基于時間值的頁面,否則瀏覽者將無法理解為何時間總是滯后。不要緩存用戶隨時都會修改的對象,如購物車。ASP.net中常用的緩存方式有:1)頁面緩存(對整個頁面進(jìn)行緩存)%/Response.AddH

38、eader(Last-Modified,DateTime.Now.AddHours(-1).ToString(r);%Response.AddHeader(Cache-Control,max-age=86400);%/Response.AddHeader(Date,DateTime.Now.AddMinutes(-59).ToString(r);%Page OutputCache VaryByParams=classid;pageDuration=3600%.net2.0中為:%OutputCache VaryByParam=classid;pageDuration=3600%你就可以有效的利

39、用第一次請求里生成的頁面輸出緩存內(nèi)容,3600秒后重新生成一道頁面內(nèi)容。這種技術(shù)其實(shí)也是運(yùn)用一些低層的Cache API來實(shí)現(xiàn)。用頁面輸出緩存有幾個參數(shù)可以配置,如上面所說的VaryByParams參數(shù),該參數(shù)表示什么時候觸發(fā)重輸出的條件,也可以指定在Http Get或Http Post請求模式下緩存輸出。例如當(dāng)我們設(shè)置該參數(shù)為VaryByParams=classid;page的時候,default.aspx?classid=3&page=1請求的輸出都會被緩存起來。沒有參數(shù),或不用參數(shù)時用none。如果傳遞的參數(shù)不止一個,那么即使字符串參數(shù)與值都相同,但排列次序不同,那么在請求頁面時,也將生

40、成不同的緩存頁。例如default.aspx?first=1&last=1和default.aspx?last=1&first=1雖然參數(shù)完全相同,但由于排列次序不同,將生成兩個不同的緩存頁。許多人都沒有意識到當(dāng)用頁面輸出緩存的時候,也會生成HTTP頭集(HTTP Header)保存在下游的緩存服務(wù)器中,這些信息可以用于Microsoft Internet安全性中以及加速服務(wù)器的響應(yīng)速度。當(dāng)HTTP緩存的頭被重置時,請求的內(nèi)容會被緩在網(wǎng)絡(luò)資源中,當(dāng)客戶端再次請求該內(nèi)容時,就不會再從源服務(wù)器上獲得內(nèi)容了,而直接從緩存中獲得內(nèi)容。雖然用頁面輸出緩存不提高你的應(yīng)用程序性能,但是它能減少

41、了從的服務(wù)器中加載已緩存頁面內(nèi)容的次數(shù)。當(dāng)然,這僅限于緩存匿名用戶可以訪問的頁面。因?yàn)橐坏╉撁姹痪彺婧?,就不能再?zhí)行授權(quán)操作了。2)片斷緩存(對頁面的某一部分,如某個User Control進(jìn)行緩存)%OutputCache Duration=60VaryByParam=TextBox1;TextBox2%在ASP.net中,除了在頁面范圍內(nèi)使用緩存,也還可以針對User Control使用Output Cache參數(shù)實(shí)現(xiàn)對用戶控件的緩存。同樣的,一個頁面中相同類型的控件也可以有多個不同的緩存??梢愿鶕?jù)參數(shù)來實(shí)現(xiàn)不同的緩存。頁面緩存和片斷緩存可以同時使用。3)數(shù)據(jù)緩存數(shù)據(jù)緩存是一種強(qiáng)大而又非常

42、簡單的緩存機(jī)制,它可以在緩存區(qū)中為每個應(yīng)用程序保存各種對象,這些對象可以根據(jù)http的請求被調(diào)用,但是在各個不同的應(yīng)用程序中這些對象都是私有的。數(shù)據(jù)緩存是通過Cache類來實(shí)現(xiàn)的。當(dāng)應(yīng)用程序建立時,一個Cache類就同時被建立,緩存實(shí)例的生存周期就是應(yīng)用程序的生存周期,它會隨著應(yīng)用程序的重新運(yùn)行而重建,通過Cache類的方法,我們可以將數(shù)據(jù)對象放入緩存區(qū),然后通過關(guān)鍵字匹配尋找并使用這些對象。Cache類通過一個借口來控制所有需要緩存的內(nèi)容,包括規(guī)定緩存的時間和緩存方式,可以通過如下方法添加緩存對象:Cache關(guān)鍵字=關(guān)鍵字的取值;然后通過下面的方法來訪問這個對象:string mKeyVal

43、ue=;if(Cache關(guān)鍵字!=null)mKeyValue=Cache關(guān)鍵字;注意Page.Cache和HttpContext.Current.Cache區(qū)別:它們指的同一個對象,在Page里,用Page.Cache,如果在global.asax或自己的類里用:HttpContext.Current.Cache,在有些事件中,由于其沒有HttpContext,就用HttpRuntime.Cache。數(shù)據(jù)緩存的過期依賴條件某種意義上,Cache和Application是一樣的,都是一種公有的對象。為了取得緩存與數(shù)據(jù)有效性之間的平衡,可以根據(jù)需要對緩存過期策略進(jìn)行合理的設(shè)置。文件依賴Cache

44、.Insert(Mydata,Source,New CacheDependency(Server.MapPath(authors.xml);此代碼的含義是當(dāng)authors.xml文件不發(fā)生變化的時候,緩存MyData始終有效。時間依賴設(shè)定1小時后過期,這是一種絕對過期。Cache.Insert(Mydata,Source,null,DateTime.Now.AddHours(1),TimeSpan.Zero);相對過期依賴當(dāng)DataSet不再發(fā)生變化20分鐘以后,緩存過期。Cache.Insert(MyData,Source,null,DateTime.MaxValue,TimeSpan.Fr

45、omMinutes(20);一個示例:/絕對過期!(用來保存公用的,數(shù)據(jù)量小的數(shù)據(jù)對象,可以是任何對象)/設(shè)置if(System.Web.HttpContext.Current.Cacheok=null)System.Web.HttpContext.Current.Cache.Insert(ok,data,null,DateTime.Now.AddSeconds(300),System.Web.Caching.Cache.NoSlidingExpiration);/讀取if(System.Web.HttpContext.Current.Cacheok!=null)this.Response.W

46、rite(Convert.ToString(System.Web.HttpContext.Current.Cache.Get(ok);最后要注意:在Web Form調(diào)試期間不能使用緩存,否則你對頁面所做的修改在緩存過期之前不會得到顯式加載。正確的做法應(yīng)該是在調(diào)試結(jié)束之后,給需要放入緩存的頁面、用戶控件或?qū)ο蠹由暇彺嬷噶?。最后建立部署和安裝項目,生成安裝數(shù)據(jù)包,這時候就可以到服務(wù)器上去發(fā)布你的產(chǎn)品了。詳細(xì)參考:.2f262cb83820c6.html 2、預(yù)請求緩存雖然Cache API設(shè)計成用來保存某段時間的數(shù)據(jù),而預(yù)請求緩存只是保存某個時期的某個請求的內(nèi)容。如果某個請求的訪問頻率高,而且這個

47、請求只需要提取,應(yīng)用,修改或者更新數(shù)據(jù)一次。那么就可以預(yù)緩存該請求。我們舉個例子來說明。在CS的論壇應(yīng)用程序中,每一個頁面的服務(wù)器控件都要求得到用于決定它的皮膚(skin)的自定義的數(shù)據(jù),以決定用哪個樣式表及其它的一些個性化的東西。這里面的某些數(shù)據(jù)可能要長時間的保存,有些時間則不然,如控件的skin數(shù)據(jù),它只需要應(yīng)用一次,而后就可以一直使用。要實(shí)現(xiàn)預(yù)請求緩存,用A的HttpContext類,HttpContext類的實(shí)例在每一個請求中創(chuàng)建,在請求期間的任何地方都可以通過HttpContext.Current屬性訪問。HttpContext類有一個Items集合屬性,在請求期間所有的

48、對象和數(shù)據(jù)都被添加到這個集合中緩存起來。和你用Cache緩存訪問頻率高數(shù)據(jù)一樣,你可以用HttpContext.Items緩存那些每個請求都要用到的基礎(chǔ)數(shù)據(jù)。它背后的邏輯很簡單:我們向HttpContext.Items中添加一個數(shù)據(jù),然后再從它里面讀出數(shù)據(jù)。五、配置web.config 1、一定要禁用調(diào)試模式在部署生產(chǎn)應(yīng)用程序或進(jìn)行任何性能測量之前,始終記住禁用調(diào)試模式。如果啟用了調(diào)試模式,應(yīng)用程序的性能可能受到非常大的影響。compilation defaultLanguage=c#debug=false/2、必要時調(diào)整應(yīng)用程序每個輔助進(jìn)程的線程數(shù)ASP.NET的請求結(jié)構(gòu)試圖在執(zhí)行請求的線程

49、數(shù)和可用資源之間達(dá)到一種平衡。已知一個使用足夠CPU功率的應(yīng)用程序,該結(jié)構(gòu)將根據(jù)可用于請求的CPU功率,來決定允許同時執(zhí)行的請求數(shù)。這項技術(shù)稱作線程門控。但是在某些條件下,線程門控算法不是很有效。通過使用與ASP.NET Applications性能對象關(guān)聯(lián)的Pipeline Instance Count性能計數(shù)器,可以在PerfMon中監(jiān)視線程門控。當(dāng)頁面調(diào)用外部資源,如數(shù)據(jù)庫訪問或XML Web services請求時,頁面請求通常停止并釋放CPU。如果某個請求正在等待被處理,并且線程池中有一個線程是自由的,那么這個正在等待的請求將開始被處理。遺憾的是,有時這可能導(dǎo)致Web服務(wù)器上存在大量

50、同時處理的請求和許多正在等待的線程,而它們對服務(wù)器性能有不利影響。通常,如果門控因子是外部資源的響應(yīng)時間,則讓過多請求等待資源,對Web服務(wù)器的吞吐量并無幫助。為緩和這種情況,可以通過更改Machine.config配置文件processModel節(jié)點(diǎn)的maxWorkerThreads和maxIOThreads屬性,手動設(shè)置進(jìn)程中的線程數(shù)限制。注意輔助線程是用來處理ASP.NET請求的,而IO線程則是用于為來自文件、數(shù)據(jù)庫或XML Web services的數(shù)據(jù)提供服務(wù)的。分配給這些屬性的值是進(jìn)程中每個CPU每類線程的最大數(shù)目。對于雙處理器計算機(jī),最大數(shù)是設(shè)置值的兩倍。對于四處理器計算機(jī),最大

51、值是設(shè)置值的四倍。無論如何,對于有四個或八個CPU的計算機(jī),最好更改默認(rèn)值。對于有一個或兩個處理器的計算機(jī),默認(rèn)值就可以,但對于有更多處理器的計算機(jī)的性能,進(jìn)程中有一百或兩百個線程則弊大于利。注意進(jìn)程中有太多線程往往會降低服務(wù)器的速度,因?yàn)轭~外的上下文交換導(dǎo)致操作系統(tǒng)將CPU周期花在維護(hù)線程而不是處理請求上。httpRuntime maxRequestLength=4096useFullyQualifiedRedirectUrl=trueminFreeThreads=8minLocalRequestFreeThreads=4appRequestQueueLimit=300executionTi

52、meout=45/Configuration setting默認(rèn)值推薦值-maxconnection 212*#CPUs maxIoThreads 20 100 maxWorkerThreads 20 100 minWorkerThreads 50 minFreeThreads 888*#CPUs minLocalRequestFreeThreads 476*#CPUs appRequestQueueLimit 1000 3、仔細(xì)選擇會話狀態(tài)提供程序ASP.NET為存儲應(yīng)用程序的會話數(shù)據(jù)提供了三種不同的方法:進(jìn)程內(nèi)會話狀態(tài)、作為Windows服務(wù)的進(jìn)程外會話狀態(tài)和SQL Server數(shù)據(jù)庫中的

53、進(jìn)程外會話狀態(tài)。每種方法都有自己的優(yōu)點(diǎn),但進(jìn)程內(nèi)會話狀態(tài)是迄今為止速度最快的解決方案。如果只在會話狀態(tài)中存儲少量易失數(shù)據(jù),則建議您使用進(jìn)程內(nèi)提供程序。進(jìn)程外解決方案主要用于跨多個處理器或多個計算機(jī)縮放應(yīng)用程序,或者用于服務(wù)器或進(jìn)程重新啟動時不能丟失數(shù)據(jù)的情況。sessionState mode=InProcstateConnectionString=tcpip=:42424sqlConnectionString=data source=;Trusted_Connection=yescookieless=falsetimeout=20/4、其他根據(jù)適當(dāng)?shù)恼埱蠛?/p>

54、響應(yīng)編碼設(shè)置來配置應(yīng)用程序。ASP.NET默認(rèn)編碼格式為UTF-8。如果您的應(yīng)用程序?yàn)閲?yán)格的ASCII,請配置應(yīng)用程序使用ASCII以獲得稍許的性能提高??紤]對應(yīng)用程序禁用AutoEventWireup。在Machine.config文件中將AutoEventWireup屬性設(shè)置為false,意味著頁面不將方法名與事件進(jìn)行匹配和將兩者掛鉤(例如Page_Load)。如果頁面開發(fā)人員要使用這些事件,需要在基類中重寫這些方法(例如,需要為頁面加載事件重寫Page.OnLoad,而不是使用Page_Load方法)。如果禁用AutoEventWireup,頁面將通過將事件連接留給頁面作者而不是自動執(zhí)行

55、它,獲得稍許的性能提升。從請求處理管線中移除不用的模塊。默認(rèn)情況下,服務(wù)器計算機(jī)的Machine.config文件中httpModules節(jié)點(diǎn)的所有功能均保留為激活。根據(jù)應(yīng)用程序所使用的功能,您可以從請求管線中移除不用的模塊以獲得稍許的性能提升。檢查每個模塊及其功能,并按您的需要自定義它。例如,如果您在應(yīng)用程序中不使用會話狀態(tài)和輸出緩存,則可以從httpModules列表中移除它們,以便請求在不執(zhí)行其他有意義的處理時,不必執(zhí)行每個模塊的進(jìn)入和離開代碼。六、其他1、適當(dāng)?shù)厥褂霉舱Z言運(yùn)行庫的垃圾回收器和自動內(nèi)存管理小心不要給每個請求分配過多內(nèi)存,因?yàn)檫@樣垃圾回收器將必須更頻繁地進(jìn)行更多的工作。另

56、外,不要讓不必要的指針指向?qū)ο?,因?yàn)樗鼈儗⑹箤ο蟊3只顒訝顟B(tài),并且應(yīng)盡量避免含F(xiàn)inalize方法的對象,因?yàn)樗鼈冊诤竺鏁?dǎo)致更多的工作。特別是在Finalize調(diào)用中永遠(yuǎn)不要釋放資源,因?yàn)橘Y源在被垃圾回收器回收之前可能一直消耗著內(nèi)存。最后這個問題經(jīng)常會對Web服務(wù)器環(huán)境的性能造成毀滅性的打擊,因?yàn)樵诘却鼺inalize運(yùn)行時,很容易耗盡某個特定的資源。2、如果有大型Web應(yīng)用程序,可考慮執(zhí)行預(yù)批編譯每當(dāng)發(fā)生對目錄的第一次請求時都會執(zhí)行批編譯。如果目錄中的頁面沒有被分析并編譯,此功能會成批分析并編譯目錄中的所有頁面,以便更好地利用磁盤和內(nèi)存。如果這需要很長時間,則將快速分析并編譯單個頁面,以便請求能被處理。此功能帶給ASP.NET性能上的好處,因?yàn)樗鼘⒃S多頁面編譯為單個程序集。從已加載的程序集訪問一頁比每頁加載新的程序集要快。批編譯的缺點(diǎn)在于:如果服務(wù)器接收到許多對尚未編譯的頁面的請求,那么當(dāng)Web服務(wù)器分析并編譯它們時,性能可能較差。為解決這個問題,可以執(zhí)行預(yù)批編譯。為此,只需在應(yīng)用程序激活之前向它請求一個頁面,無論哪頁均可。然后,當(dāng)用戶首次訪問您的站點(diǎn)時,頁面及其程序集將已被編譯。沒有簡單的機(jī)制可以知道批編譯何時發(fā)生。需一直等到CPU空

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論