c# 反射用法及效率对比

时间:2021-05-20

反射实例化类

public class Person{ public string Name { get; set; } public Person(string name) { this.Name = name; } public string Say(string msg) { return $"{Name}: {msg}"; }}class Program{ // 测试次数 const int count = 10000000; static void Main(string[] args) { CreateInstance0(); CreateInstance1(); CreateInstance2(); CreateInstance3(); CreateInstance4(); Console.Read(); } static void CreateInstance0() { Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { Person person = new Person("张三"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - new"); } static void CreateInstance1() { Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { object person = Activator.CreateInstance(typeof(Person), "张三"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - Activator.CreateInstance"); } static void CreateInstance2() { Assembly assembly = Assembly.GetExecutingAssembly(); Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { Person obj = (Person)assembly.CreateInstance("ConsoleTest.Person", true, BindingFlags.Default, null, new object[] { "张三" }, null, null); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - Assembly.CreateInstance"); } static void CreateInstance3() { Assembly assembly = Assembly.GetExecutingAssembly(); Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { Type type = assembly.GetType("ConsoleTest.Person"); object person = Activator.CreateInstance(type, "张三"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - Assembly.CreateInstance1"); } static void CreateInstance4() { Assembly assembly = Assembly.GetExecutingAssembly(); Stopwatch watch = new Stopwatch(); watch.Start(); Type type = assembly.GetType("ConsoleTest.Person"); for (var i = 0; i < count; i++) { object person = Activator.CreateInstance(type, "张三"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - Assembly.CreateInstance2"); }}
  • 通过反射实例化对象,要比直接 new 要慢 50 倍左右
  • assembly.CreateInstance 要比 Activator.CreateInstance 慢,主要的性能损耗在 Assembly.GetType

反射调用类的方法

class Program{ // 测试次数 const int count = 10000000; static void Main(string[] args) { InvokeMethod0(); InvokeMethod1(); InvokeMethod2(); InvokeMethod3(); InvokeMethod4(); Console.Read(); } static void InvokeMethod0() { Person person = new Person("张三"); Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { string name = person.Say("Hello World!"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - 直接调用"); } static void InvokeMethod1() { Person person = (Person)Activator.CreateInstance(typeof(Person), "张三"); Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { string name = person.Say("Hello World!"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - 反射缓存类调用"); } static void InvokeMethod2() { Person person = (Person)Activator.CreateInstance(typeof(Person), "张三"); MethodInfo method = typeof(Person).GetMethod(nameof(Person.Say), new Type[] { typeof(string) }); Func<string, string> func = (Func<string, string>)method.CreateDelegate(typeof(Func<string, string>), person); Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { string result = func("Hello World!"); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - 使用反射创建出来的委托调用"); } static void InvokeMethod3() { Person person = (Person)Activator.CreateInstance(typeof(Person), "张三"); MethodInfo method = typeof(Person).GetMethod(nameof(Person.Say), new Type[] { typeof(string) }); object[] parameters = new object[] { "Hello World!" }; Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { string name = (string)method.Invoke(person, parameters); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - 使用反射得到的方法缓存调用"); } static void InvokeMethod4() { Person person = (Person)Activator.CreateInstance(typeof(Person), "张三"); object[] parameters = new object[] { "Hello World!" }; Stopwatch watch = new Stopwatch(); watch.Start(); for (var i = 0; i < count; i++) { string result = (string)(typeof(Person).GetMethod(nameof(Person.Say))?.Invoke(person, parameters)); } watch.Stop(); Console.WriteLine($"{watch.Elapsed} - 直接使用反射调用"); }}
  • 反射得到实例后调用方法和直接调用方法效率一样
  • 缓存反射方法调用和直接使用反射调用都非常耗效率

以上就是c# 反射用法及效率对比的详细内容,更多关于c# 反射的资料请关注其它相关文章!

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章