【问题标题】:C# Reflection Performence HelpC# 反射性能帮助
【发布时间】:2009-11-14 19:03:45
【问题描述】:
        var property = obj.GetType().GetProperty(blockName);

        if (property == null)
        {
            var method = obj.GetType().GetMethod(blockName);

            if (method == null)
                return "[" + blockName + "]";
            else
                return method.Invoke(obj, null).ToString();
        }
        else
            return property.GetValue(obj, null).ToString();

此代码应查找名为blockName 的值的属性。如果找到该属性,则应返回其值。如果没有,它应该查找名为blockName 的函数的值。如果找到,它应该调用它并返回返回值。如果它没有找到该方法,它应该返回 [blockName's value]。

效果很好,但我正在寻找提高效率的方法。我不想将方法转换为属性或将属性转换为方法,因为将来我也会添加参数。你能帮帮我吗?

谢谢。

【问题讨论】:

    标签: c# performance reflection


    【解决方案1】:

    如果您知道签名(即返回类型和参数),那么Delegate.CreateDelegate 可以在这里非常有效地使用:

    using System;
    using System.Reflection;
    class Test
    {
        public string Foo(int i)
        {
            return i.ToString();
        }
        static void Main()
        {
            MethodInfo method = typeof(Test).GetMethod("Foo");
            Func<Test, int, string> func = (Func<Test, int, string>)
                Delegate.CreateDelegate(typeof(Func<Test, int, string>), null, method);
            Test t = new Test();
            string s = func(t, 123);
    
        }
    }
    

    请注意,对于属性,您需要查看 GetGetMethodGetSetMethod。如果您不知道签名,则此方法效果不佳,因为 DynamicInvoke 非常慢。

    要从Delegate.CreateDelegate 中受益,您必须缓存并重新使用委托实例;不要每次都重新创建它!

    对于属性,即使你不知道属性类型,也可以考虑HyperDescriptor(你需要添加1行来启用超描述符):

    using System.ComponentModel;
    class Test
    {
        public int Bar { get; set; }
        static void Main()
        {
            PropertyDescriptor prop = TypeDescriptor.GetProperties(
                typeof(Test))["Bar"];
            Test t = new Test();
            t.Bar = 123;
            object val = prop.GetValue(t);
        }
    }
    

    【讨论】:

      【解决方案2】:

      您的主要问题是 Type.GetProperty(...) 和 Type.GetMethod(...) 非常慢。缓存从这些方法返回的值,你会看到一个巨大的加速(就像这段代码快 20 倍)。

      虽然 MethodInfo.Invoke 和 PropertyInfo.GetValue 比直接调用慢,但它们对于大多数用途来说都非常快。仅在确实需要时才使用动态程序集对其进行优化 - 这需要大量工作。

      【讨论】:

      • +1 表示 GetPropertyGetMethod 对性能问题负责。
      【解决方案3】:

      执行此操作的一种方法是在此代码第一次执行时发出一个动态方法,并将其缓存。然后,后续调用会执行预生成的方法,最终会非常快。如果重复执行此代码是您看到的问题,那么这种方法可能对您很有效。如果我扼杀了解释,请原谅我。

      看看 codeplex 上的Dynamic Reflection Library

      【讨论】:

        猜你喜欢
        • 2012-04-01
        • 2011-04-06
        • 1970-01-01
        • 2016-07-23
        • 1970-01-01
        • 2012-06-04
        • 2011-10-30
        • 1970-01-01
        • 2010-09-30
        相关资源
        最近更新 更多