在研究反思和代表时,我偶然发现了这个Jon Skeet's post的第一个示例。
尽管反射以缓慢而臭名昭著,尤其是对于重复调用,但我真的不明白如何将反射方法“包装”到Delegate中可以避免其高计算成本,就像在第一个示例中建议的那样:>
MethodInfo method = typeof(string).GetMethod("IndexOf", new Type[] { typeof(char) });
Func<char, int> converted = (Func<char, int>)
Delegate.CreateDelegate(typeof(Func<char, int>), str, method);
因此,基于该示例,我为自己建立了一个简短的比较测试。我正在尝试比较对字符串IndexOf
方法的不同调用:A)直接; B)使用反射; C)使用委托。
/*
Based on
https://codeblog.jonskeet.uk/2008/08/09/making-reflection-fly-and-exploring-delegates/
*/
public class Test
{
public static void Main()
{
// Testing the performance of different calls to string method "IndexOf"
string str = "Hello World";
Stopwatch s = new Stopwatch();
float elapsed = 0;
int iterations = 10000000;
//---------
// A) Direct
//---------
for (int i = 0; i < iterations; i++)
{
// Average to reduce noise error
s.Start();
str.IndexOf('H');
s.Stop();
elapsed += s.Elapsed.Ticks;
s.Reset();
}
Console.WriteLine("A) Direct: " + (elapsed / iterations).ToString());
elapsed = 0;
//---------
// B) Reflection
//---------
MethodInfo method = typeof(string).GetMethod("IndexOf", new Type[] { typeof(char) });
for (int i = 0; i < iterations; i++)
{
// Average to reduce noise error
s.Start();
method.Invoke(str, new object[] { 'H' });
s.Stop();
elapsed += s.Elapsed.Ticks;
s.Reset();
}
Console.WriteLine("B) Reflection: " + (elapsed / iterations).ToString());
elapsed = 0;
//---------
// C) Delegate
//---------
Func<char, int> converted = (Func<char, int>)
Delegate.CreateDelegate(typeof(Func<char, int>), str, method);
for (int i = 0; i < iterations; i++)
{
// Average to reduce noise error
s.Start();
converted('H');
s.Stop();
elapsed += s.Elapsed.Ticks;
s.Reset();
}
Console.WriteLine("C) Delegate: " + (elapsed / iterations).ToString());
}
}
在我的计算机上,典型运行将返回以下内容:
A) Direct: 0.2621305
B) Reflection: 2.571738
C) Delegate: 0.2736629
1)为此目的,我的测试/测量策略是否正确?
2)我想深入解释为什么使用委托形式C)比B)更快。幕后发生了什么?
在回答特别是问题2)时,请考虑我在反思和代表方面都是初学者。请尝试详尽无遗,但可以理解。
我已经围绕其他围绕这些主题的Stackoverflow问题进行了研究,但无法解决:Performance of reflection method call vs delegate call; What is the "cost" of .NET reflection?; How costly is .NET reflection?