C#不同反射调用方法的性能差异
using System;using System.Diagnostics;
using System.Reflection;
namespace Walterlv.Demo
{
public class Program
{
static void Main(string[] args)
{
// 调用的目标实例。
var instance = new StubClass();
// 使用反射找到的方法。
var method = typeof(StubClass).GetMethod(nameof(StubClass.Test), new[] { typeof(int) });
// 将反射找到的方法创建一个委托。
var func = InstanceMethodBuilder<int, int>.CreateInstanceMethod(instance, method);
// 跟被测方法功能一样的纯委托。
Func<int, int> pureFunc = value => value;
// 测试次数。
var count = 10000000;
// 直接调用。
var watch = new Stopwatch();
watch.Start();
for (var i = 0; i < count; i++)
{
var result = instance.Test(5);
}
watch.Stop();
Console.WriteLine($"{watch.Elapsed} - {count} 次 - 直接调用");
// 使用同样功能的 Func 调用。
watch.Restart();
for (var i = 0; i < count; i++)
{
var result = pureFunc(5);
}
watch.Stop();
Console.WriteLine($"{watch.Elapsed} - {count} 次 - 使用同样功能的 Func 调用");
// 使用反射创建出来的委托调用。
watch.Restart();
for (var i = 0; i < count; i++)
{
var result = func(i);
}
watch.Stop();
Console.WriteLine($"{watch.Elapsed} - {count} 次 - 使用反射创建出来的委托调用");
// 使用反射得到的方法缓存调用。
watch.Restart();
for (var i = 0; i < count; i++)
{
var result = method.Invoke(instance, new object[] { 5 });
}
watch.Stop();
Console.WriteLine($"{watch.Elapsed} - {count} 次 - 使用反射得到的方法缓存调用");
// 直接使用反射调用。
watch.Restart();
for (var i = 0; i < count; i++)
{
var result = typeof(StubClass).GetMethod(nameof(StubClass.Test), new[] { typeof(int) })
?.Invoke(instance, new object[] { 5 });
}
watch.Stop();
Console.WriteLine($"{watch.Elapsed} - {count} 次 - 直接使用反射调用");
}
private class StubClass
{
public int Test(int i)
{
return i;
}
}
}
public static class InstanceMethodBuilder<T, TReturnValue>
{
/// <summary>
/// 调用时就像 var result = func(t)。
/// </summary>
public static Func<T, TReturnValue> CreateInstanceMethod<TInstanceType>(TInstanceType instance, MethodInfo method)
{
if (instance == null) throw new ArgumentNullException(nameof(instance));
if (method == null) throw new ArgumentNullException(nameof(method));
return (Func<T, TReturnValue>)method.CreateDelegate(typeof(Func<T, TReturnValue>), instance);
}
/// <summary>
/// 调用时就像 var result = func(this, t)。
/// </summary>
public static Func<TInstanceType, T, TReturnValue> CreateMethod<TInstanceType>(MethodInfo method)
{
if (method == null)
throw new ArgumentNullException(nameof(method));
return (Func<TInstanceType, T, TReturnValue>)method.CreateDelegate(typeof(Func<TInstanceType, T, TReturnValue>));
}
}
}
页:
[1]