天天看點

三種屬性操作性能比較:PropertyInfo + Expression Tree + Delegate.CreateDelegate一、定義測試相關的接口、類型和委托二、通過Expression Tree的方式建立用于屬性操作的委托三、編寫屬性指派操作測試方法四、編寫屬性取值操作測試方法五、執行測試程式,檢視測試結果六、如果在Expression Tree中避免類型轉換呢?

Emit。本篇繼續讨論這個話題,我們再引入另外兩種額外的屬性操作方式:Expression Tree(這和IL

目錄 一、定義測試相關的接口、類型和委托 二、通過Expression Tree的方式建立用于屬性操作的委托 三、編寫屬性指派操作測試方法 四、編寫屬性取值操作測試方法 五、執行測試程式,檢視測試結果 六、如果在Expression Tree中避免類型轉換呢?

我首先定義了一個Bar類型和IFoo接口,該接口中僅僅包含一個類型和名稱為Bar的可讀寫屬性。Foo1、Foo2和Foo3均實作接口IFoo,這些接口和類型定義如下:

然後定義如下兩個委托:GetPropertyValue和SetPropertyValue。如它們的名稱所表示的那些,它們分别表示屬性取值和指派操作:

接下來我們編寫Expression

Tree的方式完成屬性指派和取值的操作,它們實作在如下兩個靜态方法中:CreateGetPropertyValueFunc和CreateSetPropertyValueAction。下面是CreateGetPropertyValueFunc的定義,它傳回的是一個Func<object.object>委托:

下面是CreateSetPropertyValueAction方法,傳回一個Action<object.object>委托:

接下來我們編寫程式測試三種不同的屬性指派操作分别具有怎樣的性能,所有的測試代碼定義在如下TestSetPropertyValue靜态方法中。該方法參數表示進行屬性指派操作疊代的次數,每次疊代分别對Foo1、Foo2和Foo3三個對象的Bar屬性進行指派。最後列印出三種指派操作分别的耗時,時間機關為毫秒。

屬性取值操作的測試方法TestGetPropertyValue與TestSetPropertyValue結構一樣。先執行個體化三個IFoo對象(類型分别分Foo1、Foo2和Foo3),并初始化了它們的Bar屬性。然後按照三種不同的方式擷取該屬性值,并列印出它們各自的耗時。

我們直接通過一個Console應用來測試,在Main()方法中編寫了如下的測試程式。先三次調用TestSetPropertyValue方法測試屬性指派操作,傳入表示疊代次數的參數分别為10000(一萬)、100000(十萬)和1000000(一百萬)。然後按照相同的方式調用TestGetPropertyValue測試屬性取值操作。

從下面的輸出結果來看,不論是屬性的指派還是取值,單純通過PropertyInfo的方式所耗用的時間都比其它兩種形式要長的多。至于其它兩種(Expression

Tree和通過Delegate.CreateDelegate建立委托)來說,後者又比前者有明顯的優勢。

當我們調用Delegate的靜态方法CreateDelegate是,需要指定具體的委托類型。對于屬性的操作來說,屬性類型需要與指定的委托類型相比對,是以這就避免了類型轉化這個步驟。但是對于Expression

Tree的屬性操作來說,由于傳回的類型是Func<object,object>和Action<object,object>,需要對目标對象和屬性值進行兩次類型轉換。如果将類型轉換這個步驟從Expression

Tree中移掉,兩者的性能是否一緻呢?

我們不妨來試試看。現在我們修改CreateGetPropertyValueFunc和CreateSetPropertyValueAction這兩個靜态方法,讓它們直接傳回Func<IFoo,Bar>和Action<IFoo,

Bar>,并去掉Expression.Convert語句。兩個方法現在的定義如下:

在這種情況下,再次運作我們的測試程式,你會得到如下的輸出結果。從中我們不難看出,通過上面的修改,Expression Tree形式的操作在性能上得到了一定的提升,但是和第三種依然有一定的差距。

<a href="http://www.cnblogs.com/artech/archive/2011/03/24/PropertyAccessor.html">晚綁定場景下對象屬性指派和取值可以不需要PropertyInfo</a>

<a href="http://www.cnblogs.com/artech/archive/2011/03/26/Propertyaccesstest.html">三種屬性操作性能比較:PropertyInfo + Expression Tree + Delegate.CreateDelegate</a>

<a href="http://www.cnblogs.com/artech/archive/2011/03/27/ExpressTreeVsIlEmit.html">關于Expression Tree和IL Emit的所謂的"性能差别"</a>

作者:蔣金楠

微信公衆賬号:大内老A

如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識别二維碼)關注個人公衆号(原來公衆帳号蔣金楠的自媒體将會停用)。

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

<a href="http://www.cnblogs.com/artech/archive/2011/03/26/Propertyaccesstest.html" target="_blank">原文連結</a>

繼續閱讀