個人學習asp.net代碼優化經驗總結

vivian0203 12年前發布 | 2K 次閱讀 Beetl Fresh IDE kbengine

對于影響ASP.NET程序性能的因素,重要性并非按數據庫、ASP.NET代碼、前端這樣來排序,不同的應用環境可能重要的影響因素都不一樣,除去外在硬件、網絡等因素,用戶在地址欄里輸入地址,到整個網頁完整顯示在用戶的瀏覽器中,這個時間等于所有因素之和。一般情況來講,在正常的情況下,處理這三種因素都需要不同的角色:DBA負責數據庫優化,程序員優化ASP.NET代碼、前端工程師優化前端性能,如果分工沒有這么明細,就會出現分工出現交叉的情況;最壞的情況是,只有一個人,這個人既是DBA,又是程序員,還要書寫全部前端部分。——這可能是件壞事,你在一個摳門的老板手里,老板把你當驢子來用;也會是一件好事,Web開發本身就是一件需要掌握眾多知識的工作,你會從中學習到更多的知識,這樣對理解網絡程序會有更全面的認識(偶就是這么過來的…………TAT)。

一、慎用服務器控件

ASP.NET中的服務器控件一部分是對html控件的擴展,包括Button、Label、Literal、TextBox、DropDownList、CheckBox、RadioButton等,ASP.NET對這些控件進行了封裝,同時對控件進行了委托事件的綁定,這樣使得ASP.NET程序員就可以像VB、WinFornm那樣拖控件的方式來去對界面進行布局和事件的處理。這類控件生成的HTML控件基本不會生成多余的代碼,如果對Web標準不是很在意的話,影響不會很大。值得一提的是Label生成的是標簽,CheckBox(List)、RadioButton(List)生成的標簽往往是這樣的:

<span class="checkBox"><input id="chkSel" type="checkbox" name="chkSel"  /><label for="chkSel">選擇</label>

這種代碼從Web標準上來看是要被前端工程師罵的,既無語義性又浪費代碼。

另一類服務器控件就是微軟引以為傲的大數據展示控件,包括GridView、DataList、DetailsView、ListView、Repeater等,這類控件除了Repeater控件外,其他不推薦使用,這類傻瓜控件會把程序員變得更加傻瓜,更重要的是會影響代碼性能,以GridView為例,在綁定DataSource后,所有的數據都會在服務器的內存上一次加載,程序員最愛它的分頁功能——瞧,點幾下就可以了。但如果數據比較多,比如幾百頁、幾千頁,點一次等待的時間可以上一次廁所。Repeater控件推薦使用,因為它不會生成任何代碼,僅是將數據源的內容重復顯示出來。對于最最常用的分頁功能建議是存儲過程+Repeater,這樣無論是從性能還是從HTML代碼整潔度來看都是合適的。

HTML算是Web開發者最最基本的能力,如果不能手寫HTML很難勝任Web開發這項工作,使用Visual Studio拖控件得來的代碼是非常混亂的,建議還是打開源視圖一行一行地寫HTML,即使它是服務器控件。

一、ViewState的問題

ViewState本身是一個非常好的想法,微軟的創新能力在業界是公認的,起因是這樣的:用戶向服務器提交數據,比如姓名、年齡、性別等,服務器會對這些數據的合法性進行驗證,如果格式不正確或者輸入為空這樣服務器就會將一些錯誤信息返回給用戶,但問題是用戶剛剛提交的表單內容都已經沒有了,如果表單中要填寫的內容比較多,用戶會發瘋的。這時ASP.NET就非常好心地把這些提交的內容都還存儲在這個網頁里,即使數據提交未通過驗證,這些數據依然保持在它本來的位置上 ,這個做法非常的討好用戶和開發者,對了,它往往和驗證控件一起使用,看似非常人性化,但它卻是會生成大量臃腫代碼的罪魁禍首。

這種亂七八糟的代碼是對已有的數據進行Base64加密后產生的結果,它會讓用戶的瀏覽器在下載你的網頁時感覺慢了一些。

我的觀點是,如果是互聯網類產品(包含網站類)要全局把EnableViewState設為false,可以在Web.Config里設置的。解決方案是使用Javascript進行驗證,現在的表單驗證庫使用起來是很方便的。

三、ADO.NET中的問題

1、SqlDataReader和DataSet的選擇:

SqlDataReader是一種快速向前讀取數據的類,它對于從Sql Server數據源檢索的數據采用只進數據流的方式,DataSet會將數據庫的內容以邏輯數據庫的方式存放在服務器的內存中,如果數據量比較大,對服務器的性能影響就比較大了。因此在實際項目中應該合理選擇。

2、ExecuteNonQuery和ExecuteScalar的選擇:

ExecuteScalar會返回執行結果后的第一行第一列數據,ExecuteNonQuery只會返回影響的行數,在一些情況下我們可能只需要知道是否已經執行成功了,也就是ExecuteNonQuery返回的行數是否大于0;有的時候我們還想知道返回結果的數據,比如在執行INSERT后我們需要使用SCOPE_IDENTITY()來得到返回的主鍵ID。可以根據實際需要選擇使用ExecuteNonQuery和ExecuteScalar。

四、合理使用緩存

使用緩存算是屬于重中之重,這個可以這么來解釋:當有一百個人都需要到服務器取一個數據,那么程序每次都會到SQL Server數據庫中查詢取出數據,這樣將對性能造成很大的影響。可以將這個數據暫時緩存到服務器上,這樣第一個人查詢時會將這個數據存到服務器的內存上,其余的用戶在緩存時間內都會直接從服務器上取出這個數據,避免多次請求數據源,這樣就會提升程序的性能。當然,如果是這個緩存數據是動態變化的話,可以適當的設置緩存時間,或者在更新數據時清除緩存,這種情況比如在文章系統中會遇到。

五、其他優化

1、避免拆箱裝箱:

我們知道C#中的值類型和引用類型,C#基礎數據類型和Struct、Enum屬于值類型,引用類型包括類、數組、接口、委托以及字符串(String),不錯,字符串也屬于引用類型;值類型會以棧(Stack)的形式存儲在內存,引用類型會以堆(Heap)的形式存儲(這個概念也就是C語言的指針)。值類型轉換為引用類型稱為裝箱,反之稱為拆箱。如下:

1
2
3
int i=0;
Syste.Object obj=i;//裝箱
int j=(int)obj;//拆箱

 

裝箱拆箱會影響程序性能,我們在程序中應該盡可能避免。因此程序這樣寫會提升那么一點點的性能:

1
String info="My Age is" + 24.ToString();
2、使用StringBuilder

如果字符串拼接過多,可能會影響程序性能,這樣因為每次++都會創新一個新的字符串,也就是說會在內存中多開辟了一個空間給這個新的字符串。使用StringBuilder可以減少這種消耗。建議在連接字符串過多的情況下使用。

另外記得關于StringBuilder的問題曾經在博客園爭吵過一次,如果有問題歡迎大家指出來。

3、避免不必要的ToLower()和ToUpper()

同上一樣,都會創建新的字符串對象,如果沒有必要盡量減少使用,也可以使用Compare方法來比較字符串。

4、避免不必要的異常捕獲

也許你對事物的考慮過于復雜,對于異常的捕獲也過于敏感,于是Try…Catch就用得多一點,那么建議還是在該用的時候才用,不該用的時候不用。

5、使用存儲過程

頻繁的SQL語句在Web服務器傳遞到數據庫服務器上來回傳輸會影響程序執行的效率,更為有效的方式就是把語句比較復雜和需要比較頻繁使用的SQL語句封裝成存儲過程進行調用。

總結

以上是我個人總結的ASP.NET代碼優化的一點方法和心得,這個層面的優化需要更多的是對C#語言、ADO.NET機制和ASP.NET運行機制掌握得更多和更加深入。優化無止境,歡迎完善和補充。

推薦視頻
《VS2010輕松學習C#-從零到深入-天轟穿.NET4趣味編程視頻教程》
《蕭諫弢C#入門基礎與程序基本邏輯實現教程》
《天轟穿之VS2010 c#趣味編程實例實戰系列視頻教程》

 本文由用戶 vivian0203 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!