以前我很早就被植入使用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)
Generic advanced Delegate.CreateDelegate using expression trees
Generic Method Invocation with Expression Trees
Dynamically call C# instance method by "string" name, without performance overhead.