• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

软件测试中有关Emit与Reflection性能对比测试

发布: 2009-5-21 10:17 | 作者: 不详 | 来源: 测试时代采编 | 查看: 228次 | 进入软件测试论坛讨论

领测软件测试网 使用Emit代替反射性能提升比较多,不过使用Emit需要将DynamicMethod缓存起来,缓存太多也不好,所以可以使用一些折中方法。
例如NHibernate,使用Emit读取/设置实体属性时,生成的DynamicMethod每次读取/设置全部的属性值,读取时返回一个object[],设置时提供一个包含各个属性值的object[]数组。在SELECT时使用这种方式一次设置好所有属性;在INSERT、UPDATE时则一次读出全部属性;在DELETE时则可以直接使用反射从实体上读取identity属性,因为从应用层面总体来看反射的性能还是比较好的。

Emit跟反射的性能测试对比如下:

Emit、Reflection代码:
//A delegate for the dynamic method
public delegate object GetPropertyValueInvoker(object obj);

public class EmitTest
{
    private static GetPropertyValueInvoker GetEmitInvoker(Type type, string propertyName)
    {
        PropertyInfo propInfo = type.GetProperty(propertyName
            , BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

        //Create a DynamicMethod
        Type ownerType = type.IsInterface ? typeof(object) : type;
        bool canSkipChecks = SecurityManager.IsGranted(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess));
        DynamicMethod method = new DynamicMethod(string.Empty, typeof(object)
            , new Type[] { typeof(object) }, ownerType, canSkipChecks);

        //Use ILGenerator to build the method body’s IL code
        ILGenerator il = method.GetILGenerator();
        //Load the first argument of the method call onto stack
        il.Emit(OpCodes.Ldarg_0);
        //Necessary type conversion
        if (type.IsValueType)
            il.Emit(OpCodes.Unbox, type);
        else [Page]
            il.Emit(OpCodes.Castclass, type);
        //Call the property’s get method
        il.EmitCall(OpCodes.Callvirt, propInfo.GetGetMethod(true), null);
        //If getter return a value type, box it to object
        if (propInfo.PropertyType.IsValueType)
        {
            il.Emit(OpCodes.Box, propInfo.PropertyType);
        }
        //Return the value of the property
        il.Emit(OpCodes.Ret);

        //Create a delegate for the client to call the dynamic method
        GetPropertyValueInvoker getInvoker = 
            (GetPropertyValueInvoker)method.CreateDelegate(typeof(GetPropertyValueInvoker));

        return getInvoker;
    }
    //simply cache the dynamic method for the type TestEntity
    private static IDictionary<string, GetPropertyValueInvoker> _invokerCache 
        = new Dictionary<string, GetPropertyValueInvoker>(3);

    //Use the dynamic method, which is generated by using Emit every time, to  get the property’s value

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/

TAG: 软件测试 性能 Reflection Emit

31/3123>

关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网