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

- 通过反射实例化对象,要比直接 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#中@标志的作用  C#通过序列化实现深表复制  细说并发编程-TPL  大数据量下DataTable To List效率对比  【转载】C#工具类:实现文件操作File的工具类  异步多线程 Async  .net 多线程 Thread ThreadPool Task  .Net 反射学习
		c#中@标志的作用 参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ... 
- golang 浮点数 取精度的效率对比
		需求 浮点数取2位精度输出 实现 代码 package main import ( "time" "log" "strconv" " ... 
- string中Insert与Format效率对比、String与List中Contains与IndexOf的效率对比
		关于string的效率,众所周知的恐怕是“+”和StringBuilder了,这些本文就不在赘述了.关于本文,请先回答以下问题(假设都是基于多次循环反复调用的情况下):1.使用Insert与Forma ... 
- 关于 pgsql 数据库json几个函数用法的效率测试
		关于 pgsql 数据库json几个函数用法的效率测试 关于pgsql 几个操作符的效率测试比较1. json::->> 和 ->> 测试方法:单次运行100次,运行10个单次 ... 
- 转 SQL Union和SQL Union All两者用法区别效率以及与order by 和 group by配合问题
		SQL Union和SQL Union All两者用法区别效率以及与order by 和 group by配合问题 SQL Union和SQL Union All用法 SQL UNION 操作符 UN ... 
- FileInputStream 与 BufferedInputStream 效率对比
		我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3550158.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ... 
- java中多种写文件方式的效率对比实验
		一.实验背景 最近在考虑一个问题:“如果快速地向文件中写入数据”,java提供了多种文件写入的方式,效率上各有异同,基本上可以分为如下三大类:字节流输出.字符流输出.内存文件映射输出.前两种又可以分为 ... 
- SIMD---SSE系列及效率对比
		SSE(即Streaming SIMD Extension),是对由MMX指令集引进的SIMD模型的扩展.我们知道MMX有两个明显的缺点: 只能操作整数. 不能与浮点数同时运行(MMX使用FPU寄存器 ... 
- Snapman系统中TCC执行效率和C#执行效率对比
		Snapman集合了TCC编译器可以直接编译执行C语言脚本,其脚本执行效率和C#编译程序进行效率对比,包括下面4方面: 1.函数执行效率 2.数字转换成字符串 3.字符串的叠加 4.MD5算法 这是C ... 
随机推荐
- 【算法】ST表
			想学习一下LCA倍增,先 水一个黄题 学一下ST表 ST表 介绍: 这是一个运用倍增思想,通过动态规划来计算区间最值的算法 算法步骤: 求出区间最值 回答询问 求出区间最值: 用f[i][j]来存储从 ... 
- 性能优化(CSS优化)
			高质量的CSS代码体现在三个方面:可读性和可维护性和高性能.对于"前端工程师"来说如何平衡"追求高性能"和"可维护性"是很值得思考的问题. ... 
- Prometheus 初探和配置(安装测试)
			本文大纲: • Prometheus 官⽹下载• Prometheus 开始安装• Prometheus 启动运⾏• Prometheus 基本配置⽂件讲解• 安装第⼀个exporter => ... 
- linux下的ARP攻击(kali)
			这是我的学习总结,刚入坑网络安全,写的不好或者有什么错误的希望大佬们指正 首先了解ARP的作用以及原理: ARP(Address Resolution Protocol,地址解析协议)是一个位于TCP ... 
- python  --装饰器通俗讲解
			装饰器 什么是装饰器?:在不修改源代码和调用方式的基础上给其增加新的功能,多个装饰器可以装饰在同一个函数上 Python中的装饰器是你进入Python大门的一道坎; 装饰器特点: 不改变原函数原代码: ... 
- Linux常用命令详解(第一章)(ls、man、pwd、cd、mkdir、echo、touch、cp、mv、rm、rmdir、)
			本章命令(共11个): 1 2 3 4 5 6 ls man pwd cd mkdir echo touch cp mv rm rmdir 1. " ls " 作用:列出指定目录下 ... 
- UML——关系
			 一.宏观导图: 二.细节 1.关联:指的是类与类之间的结构性关系,即整体-部分关系.一般的关联关系中有单向的和双向的. 特殊关联中的,有聚合和组合,其实我更愿意用英文去理解,这些人翻译的让我很恶 ... 
- Spark+Kafka实时监控Oracle数据预警
			目标: 监控Oracle某张记录表,有新增数据则获取表数据,并推送到微信企业. 流程: Kafka实时监控Oracle指定表,获取该表操作信息(日志),使用Spark Structured Strea ... 
- Kwp2000协议的应用(程序后续篇)
			作者:良知犹存 转载授权以及围观:欢迎添加微信:becom_me 总述 接上篇文章,本篇继续对基于PID解析数据,如何依据J1979的标准进行解析数据 先给昨天的文章补上一张故障码对照表,昨天分析了如 ... 
- HDU6191 Query on A Tre【dsu on tree + 01字典树】
			Query on A Tree Problem Description Monkey A lives on a tree, he always plays on this tree. One day, ... 
