c# 反射用法及效率对比

作者:丹枫无迹 时间:2022-06-11 17:50:19 

反射实例化类


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# 反射用法及效率对比

  • 反射得到实例后调用方法和直接调用方法效率一样

  • 缓存反射方法调用和直接使用反射调用都非常耗效率

来源:https://www.cnblogs.com/gl1573/p/14411427.html

标签:c#,反射,效率
0
投稿

猜你喜欢

  • Logback 使用TurboFilter实现日志级别等内容的动态修改操作

    2022-06-10 04:17:53
  • java实现简单登录界面的实战过程

    2022-02-07 20:19:51
  • Java数据结构专题解析之栈和队列的实现

    2022-11-20 01:24:21
  • 详解SpringBoot定制@ResponseBody注解返回的Json格式

    2023-07-26 13:47:02
  • Java爬取豆瓣电影数据的方法详解

    2021-12-12 16:21:06
  • Java反转链表测试过程介绍

    2022-10-02 20:10:03
  • autoMapping和autoMappingBehavior的区别及说明

    2023-11-29 06:39:25
  • Java selenium处理极验滑动验证码示例

    2023-12-19 19:10:09
  • JVM教程之内存管理和垃圾回收(三)

    2023-11-10 15:49:54
  • 基于集合的子集与集合的全排列的相关问题

    2023-09-23 07:03:46
  • 基于spring AOP @Around @Before @After的区别说明

    2023-12-15 03:08:25
  • SpringCloud Eureka的使用教程

    2022-03-23 22:30:59
  • spring springMVC中常用注解解析

    2023-09-14 20:45:46
  • springboot 如何设置端口号和添加项目名

    2022-01-11 07:31:12
  • C#键值对容器的介绍

    2023-04-14 12:26:56
  • springboot 注解方式批量插入数据的实现

    2022-02-20 19:03:50
  • springboot结合vue实现增删改查及分页查询

    2023-11-24 15:53:44
  • 简单了解Java多态向上转型相关原理

    2023-10-11 16:11:01
  • Spring MVC 处理一个请求的流程

    2021-12-19 18:39:39
  • java面试try-with-resources问题解答

    2023-09-03 15:08:01
  • asp之家 软件编程 m.aspxhome.com