[C#]dynamic call VS direct call

以前我很早就被植入使用Reflection大部分效能都不好,所以應該要盡量避免,

但朋友昨天傳給我一篇文章指出現在的dynamic call不會有效能問題,

雖然我知道C#早已不是以前的吳下阿蒙了,但我還是覺得應該還是有效能上的差異,

所以我這裡簡單測試dynamic call 和 direct call兩者效能差異。

public class TestClass
    {
        [Test]
        public void TestWithPerformance()
        {          
            var stopWatch = new Stopwatch();
            stopWatch.Start();          
            var method = typeof(MyRedis).GetMethod("ShowValue");
            var action = (Action<MyRedis>)Delegate.CreateDelegate(typeof(Action<MyRedis>), method);
            //Dynamic call
            for (int i = 0; i < 1000; i++)
            {
                action(null);
            }       
            stopWatch.Stop();
            System.Console.WriteLine($"Dynamic call(ms):{stopWatch.Elapsed.TotalMilliseconds}");

            //Direct call 
            stopWatch.Restart();  
            var myRedis = new MyRedis();
            for (int i = 0; i < 1000; i++)
            {
                myRedis.ShowValue();
            }       
            stopWatch.Stop();
            System.Console.WriteLine($"Direct call(ms):{stopWatch.Elapsed.TotalMilliseconds}");
        }

    }

    public class MyRedis
    {
        public void ShowValue()
        {
            //Console.WriteLine($"ricoisme");           
        }
        //public string GetValue() => "ricoisme";

    }

Call 1000 times(效能相差26倍)

Call 10000 times(效能相差3.4倍)

Call 500000 times(效能相差1.5倍)

結論:

dynamic call效能依然不佳,雖然次數越多,兩者差異越小,但還是請盡量避免。

 

參考

Delegate.CreateDelegate Method (Type, MethodInfo)

Expression.Call Method (Expression, MethodInfo)

How slow is Reflection

Generic advanced Delegate.CreateDelegate using expression trees

Generic Method Invocation with Expression Trees

Dynamically call C# instance method by "string" name, without performance overhead.

Improving Reflection Performance with Delegates