【问题标题】:C# Reflection performance comparison when invoking class with parameter带参数调用类时的C#反射性能比较
【发布时间】:2020-04-02 17:09:11
【问题描述】:

我听说过很多关于 Linq Expression 性能的信息。但自己无法检查。 请查看下一个 .NET Core 应用示例:

 class Program
    {
        static void Main(string[] args)
        {
            var classType = Type.GetType("ConsoleApp1.TestClass");
            var classConstructor = classType.GetConstructor(new[] { typeof(string) });

            //var param = Expression.Parameter(typeof(string));
            //var newExpression = Expression.New(classConstructor, param);
            //LambdaExpression lambda = Expression.Lambda(newExpression, param);
            //var compiled = lambda.Compile();
            //var instance = compiled.DynamicInvoke("test");

            //var instance = Activator.CreateInstance(classType, "test");

            //var instance = classConstructor.Invoke(new object[] { "test" });

            Console.ReadLine();
        }
    }

    class TestClass
    {
        public TestClass(string param)
        {

        }
    }

当我在未注释 Expression 版本的情况下运行此代码时,代码的运行速度会慢 10 倍。 请告知可能出现的问题或符合预期。

【问题讨论】:

  • 你执行了多少次实例化?您应该同时保留 classConstructor compiled 变量,然后进行热身(调用这三个变量几次),然后开始您的基准测试
  • 这完全取决于你“听说过很多关于Linq Expression 性能”...通常是“不要使用反射调用某物百万次,编译一次表达式并使用它百万次,或使用dynamic 为您缓存反射,或至少缓存大部分反射调用“...将单个反射调用与创建表达式进行比较绝对不会显示出好处...
  • 我的意思是,lambda表达式编译一次,编译后的表达式应该保存。反射构造函数检索也必须发生一次并且应该被存储。然后,只有这样,您才能运行已编译的 lambda / ConstructorInfo 实例化比较基准。
  • DynamicInvoke 比反射还要糟糕。编译表达式在编译为强类型委托并使用 Invoke 调用时才有意义。
  • 如果我们要编译一次并运行它数百万次,那么使用 Roslyn(或 CodeDom)编译一个实现接口以创建实例的具体类怎么样? (也有强类型)。我猜没有什么能比得上:)

标签: c# performance reflection linq-expressions


【解决方案1】:

一个简单的基准测试显示了有趣的结果。持续时间以毫秒为单位。

我只是想分享我得到的结果。似乎 DynamicInvoke 确实有很大的开销(正如@ivan-stoev 指出的那样)

我将添加具有强类型 lambda 的 .Invoke 解决方案和实现简单实例化接口的 Roslyn 编译的具体类的结果。

ConstructorInfo 被缓存,编译后的 lambda 表达式也是如此。

每个 1000 万次迭代:(每个方法 1 亿次实例化)

---------------------------------------------------------------------------
Benchmark Results:
---------------------------------------------------------------------------
                    Activator           Constructor         Compiled Lambda
---------------------------------------------------------------------------

Totals :            8121.2488           3067.6226           9353.8141


Average:            0.00081212488       0.00030676226       0.00093538141


Maximum:            922.5987            450.7662            1046.3734


Minimum:            0                   0                   0


---------------------------------------------------------------------------

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多