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");
}
}
通过反射实例化对象,要比直接 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} - 直接使用反射调用");
}
}
反射得到实例后调用方法和直接调用方法效率一样
缓存反射方法调用和直接使用反射调用都非常耗效率
来源:https://www.cnblogs.com/gl1573/p/14411427.html
标签:c#,反射,效率
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Logback 使用TurboFilter实现日志级别等内容的动态修改操作
2022-06-10 04:17:53
java实现简单登录界面的实战过程
2022-02-07 20:19:51
![](https://img.aspxhome.com/file/2023/2/67152_0s.jpg)
Java数据结构专题解析之栈和队列的实现
2022-11-20 01:24:21
![](https://img.aspxhome.com/file/2023/2/61592_0s.jpg)
详解SpringBoot定制@ResponseBody注解返回的Json格式
2023-07-26 13:47:02
Java爬取豆瓣电影数据的方法详解
2021-12-12 16:21:06
![](https://img.aspxhome.com/file/2023/1/79871_0s.png)
Java反转链表测试过程介绍
2022-10-02 20:10:03
autoMapping和autoMappingBehavior的区别及说明
2023-11-29 06:39:25
Java selenium处理极验滑动验证码示例
2023-12-19 19:10:09
![](https://img.aspxhome.com/file/2023/2/74892_0s.png)
JVM教程之内存管理和垃圾回收(三)
2023-11-10 15:49:54
![](https://img.aspxhome.com/file/2023/2/59352_0s.jpg)
基于集合的子集与集合的全排列的相关问题
2023-09-23 07:03:46
基于spring AOP @Around @Before @After的区别说明
2023-12-15 03:08:25
![](https://img.aspxhome.com/file/2023/6/81966_0s.jpg)
SpringCloud Eureka的使用教程
2022-03-23 22:30:59
![](https://img.aspxhome.com/file/2023/8/70348_0s.png)
spring springMVC中常用注解解析
2023-09-14 20:45:46
springboot 如何设置端口号和添加项目名
2022-01-11 07:31:12
![](https://img.aspxhome.com/file/2023/5/78335_0s.png)
C#键值对容器的介绍
2023-04-14 12:26:56
springboot 注解方式批量插入数据的实现
2022-02-20 19:03:50
![](https://img.aspxhome.com/file/2023/2/71692_0s.jpg)
springboot结合vue实现增删改查及分页查询
2023-11-24 15:53:44
![](https://img.aspxhome.com/file/2023/3/59783_0s.jpg)
简单了解Java多态向上转型相关原理
2023-10-11 16:11:01
Spring MVC 处理一个请求的流程
2021-12-19 18:39:39
![](https://img.aspxhome.com/file/2023/1/77341_0s.png)
java面试try-with-resources问题解答
2023-09-03 15:08:01
![](https://img.aspxhome.com/file/2023/9/78949_0s.png)