欢迎光临
我的个人博客网站

【C#】反射的用法及效率对比


反射实例化类

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");     } } 

【C#】反射的用法及效率对比

  • 通过反射实例化对象,要比直接 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#】反射的用法及效率对比

  • 反射得到实例后调用方法和直接调用方法效率一样
  • 缓存反射方法调用和直接使用反射调用都非常耗效率
赞(0) 打赏
未经允许不得转载:张拓的天空 » 【C#】反射的用法及效率对比
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

专业的IT技术经验分享 更专业 更方便

联系我们本站主机

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏