天天看点

三种属性操作性能比较: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>

继续阅读