【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 ...
随机推荐
- cogs 2566 字符串最大值
2566. [51nod 1129] 字符串最大值 ★★ 输入文件:string_maxval.in 输出文件:string_maxval.out 简单对比时间限制:1 s 内存限制: ...
- 2021年,python的入门基础-----基础一
先记录下pycharm编译器相关的信息 1.某些常用快捷键: Ctrl+/ 注释: Tab缩进,shift+Tab; Ctrl+Z 撤销 2.设置界面编辑风格: File>Settings> ...
- 六:SpringBoot-引入JdbcTemplate,和多数据源配置
SpringBoot-引入JdbcTemplate,和多数据源配置 1.JdbcTemplate对象 1.1 JdbcTemplate核心方法 2.SpringBoot中使用JDBCTemplate ...
- HBase,以及GeoMesa设计基于HBase的设计分析,从数据模型到典型查询场景,最后进行RowKey设计
GeoMesa设计基于HBase的设计分析,从数据模型到典型查询场景,最后进行RowKey设计 一.HBase 基本概念 理解KeyValue KeyValue多版本 列定义(1) 列定义(2) Co ...
- mysql在8.0版本下修改密码的命令
ubuntu20.04上边部署了一个新的mysql服务,默认没密码,想要修改密码. 使用如下手段 第一种:ALTER USER 'root'@'localhost' IDENTIFIED BY '密码 ...
- NodeMCU获取并解析心知天气信息
NodeMCU获取并解析心知天气信息 1 注册心知天气并获取私钥 打开心知天气网站,点击注册按钮 填写基本信息注册心知天气账号,登录注册所填写的邮箱点击链接进行账号激活,随后出现如下界面 点击登录按钮 ...
- Python爬虫笔记一(来自MOOC) Requests库入门
Python爬虫笔记一(来自MOOC) 提示:本文是我在中国大学MOOC里面自学以及敲的一部分代码,纯一个记录文,如果刚好有人也是看的这个课,方便搬运在自己电脑上运行. 课程为:北京理工大学-嵩天-P ...
- sh 脚本名字和./脚本名字有什么区别
sh xxx用 sh 这个shell (sh一般指系统默认shell,比如 bash, ksh, Csh 等都有可能) 来解释和运行 xxx 这个脚本.xxx 文件不必具有可执行属性(chmod +x ...
- 《Proxy系列专题》:代理模式(静态、JDK、CGLib)
<Proxy系列专题>:代理模式(静态.JDK.CGLib)使用 现象:在如今互联网时代,项目的复杂度不断的提升,有些场景下需要一定的设计优化来支撑业务的扩展,如为了不改动原始类,但需要对 ...
- java的静态代码块和类变量的隐式覆盖
静态代码块特点:随着类的加载执行一次,且仅会执行一次 作用:初始化类中的static修饰的变量(static修饰的变量称为类变量.类变量和静态代码块差不多,类变量仅会被初始化一次) 一.静态代码块写法 ...