ASP.NET中的数据绑定:哪个更快? (转)
ASP.NET使用動態(tài)編譯技術(shù),在運行時動態(tài)將同一目錄的*.aspx文件先生成*.cs,然后調(diào)用CompilerServices將其編譯成assemblies(可以到你的%SYSTEMROOT%\Microsoft.NET\Framework\V1.x.xxxx\Temporary ASP.NET Files下面看看)。因此了解ASP.NET編譯的過程是優(yōu)化ASP.NET運行效率的關(guān)鍵之一。以常用的數(shù)據(jù)綁定語法為例,我們可以發(fā)現(xiàn)它的轉(zhuǎn)化規(guī)則是:
.aspx:? data-binding expression %>
->
.cs: System.Convert.ToString(data-binding expression);
其中data-binding expression是原封不動復(fù)制過來的,這樣你寫數(shù)據(jù)綁定表達式的時候就心里有譜了吧。關(guān)于常見于數(shù)據(jù)綁定表達式中的Container、DataItem、DataBinder.Eval是這樣:DataBinder是System.Web里面的一個靜態(tài)類,它提供了Eval方法用于簡化數(shù)據(jù)綁定表達式的編寫,但是它使用的方式是通過Reflection等開銷比較大的方法來達到易用性,因此其性能并不是最好的。而Container則根本不是任何一個靜態(tài)的對象或方法,它是ASP.NET頁面編譯器在數(shù)據(jù)綁定事件處理程序內(nèi)部聲明的局部變量,其類型是可以進行數(shù)據(jù)綁定的控件的數(shù)據(jù)容器類型(如在Repeater內(nèi)部的數(shù)據(jù)綁定容器叫RepeaterItem),在這些容器類中基本都有DataItem屬性,因此你可以寫Container.DataItem,這個屬性返回的是你正在被綁定的數(shù)據(jù)源中的那個數(shù)據(jù)項。如果你的數(shù)據(jù)源是DataTable,則這個數(shù)據(jù)項的類型實際是DataRowView。
現(xiàn)在你可以想想下面哪種寫法效率最高(以Repeater+DataTable數(shù)據(jù)源為例):
NOTE: 后兩種用法需要引入System.Data名稱空間……答案一天后揭曉,歡迎有空的朋友自己測試得出結(jié)論!
揭曉+簡要分析:
乍一看1-3都是使用DataBinder.Eval方法來進行數(shù)據(jù)綁定計算,而4-5是使用strong type直接獲取數(shù)據(jù)綁定的值。按照我之前的推理,很多朋友會認為4-5都會比1-3快,而實際上第4種用法也是在網(wǎng)上很常見的一種針對DataBinder.Eval而進行的“優(yōu)化”。
實際上根據(jù)我們的測試,第4種寫法的效率在某些很常見的情形下(即傳入的字段名與數(shù)據(jù)表內(nèi)部的字段名大小寫有出入時)甚至比不上最普遍的第1種寫法。不過原理還是對的,就是避免通過reflection或類似機制(如System.ComponentModel中的PropertyDescriptor機制)獲得數(shù)據(jù),然而使用DataRowView的indexer的效率在字段數(shù)量較多導(dǎo)致Hashtable產(chǎn)生尋址沖突時不如使用其Row屬性(DataRow類型)的indexer的效率。原因是DataRowView的indexer實現(xiàn)了view的功能,而這個功能對于大多數(shù)應(yīng)用在這個場合都是不需要的,且它的開銷甚至比DataBinder.Eval還要大!(本段內(nèi)容過于武斷,在被反復(fù)質(zhì)疑之下我又做了若干試驗尋得正確原因)因此簡單的使用第五種寫法通常是可以獲得較佳的性能的,而最好不要在不必要的時候直接使用DataRowView的indexer。
現(xiàn)在回到1-3的討論。首先一點,請大家注意看Eval方法的二種overload:
object DataBinder.Eval(object container, string expression)
string DataBinder.Eval(object container, string expression, string format)
注意到ASP.NET在生成的.cs文件中是使用System.Convert.ToString來將Eval的結(jié)果轉(zhuǎn)換成string的,因此顯式的提供值為null或String.Empty的format參數(shù)將使得Eval首先調(diào)用第一種方法得到綁定結(jié)果的對象,然后直接調(diào)用該對象的ToString()方法將其返回到Convert.ToString方法,對于該方法編譯器已經(jīng)在編譯期將其連接到Convert.ToString(string)的重載上,而該方法則直接返回傳入的字串。那如果直接使用第一種方法呢?雖然第二種方法是先調(diào)用第一種方法的,但是由于它的返回值是object類型,編譯器將為其選擇Convert.ToString(object)的重載,在這個重載方法中將進行一些額外的判斷以將對象轉(zhuǎn)換為string類型,而這些額外判斷顯然帶來了額外的開銷——盡管基本上算不得主要矛盾。
至于說第3種寫法,由于在expression參數(shù)中多引入了一層間接,因此需要多進行一次反射以解析表達式,因此效率非常之低。
那這里再賣個關(guān)子,請推測第5種方法是否還可以進一步優(yōu)化?(我是指在最常見的ASP.NET開發(fā)情形中):P
通過上面的分析,我們可以得到下面的結(jié)論:
希望我的這點兒心得對您有所啟發(fā)。:)
原文:http://www.cnblogs.com/dudu/articles/48608.html
轉(zhuǎn)載于:https://www.cnblogs.com/dagon007/archive/2005/03/14/118165.html
總結(jié)
以上是生活随笔為你收集整理的ASP.NET中的数据绑定:哪个更快? (转)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 有关97式军车牌照
- 下一篇: 如何计算和控制好项目开发成本?