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# 反射的资料请关注我们其它相关文章!

(0)

相关推荐

  • 详解C# 反射(Reflection)

    C# 反射(Reflection) 反射指程序可以访问.检测和修改它本身状态或行为的一种能力. 程序集包含模块,而模块包含类型,类型又包含成员.反射则提供了封装程序集.模块和类型的对象. 您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型.然后,可以调用类型的方法或访问其字段和属性. 优缺点 优点: 1.反射提高了程序的灵活性和扩展性. 2.降低耦合性,提高自适应能力. 3.它允许程序创建和控制任何类的对象,无需提前硬编码目标类. 缺点: 1.性能问题:使用反射基本

  • C#高效反射调用方法类实例详解

    C#高效反射调用方法类 1.创建一个业务类(HomeService),在类下创建3个方法 2.正常方式调用类的方法 3.反射方式调用类的方法 4.调用代码 5.调用结果 6.Service类方法代码 内容扩展: 1.正常方式调用类的方法 /// <summary> /// 正常调用类的方法(parm1) /// </summary> /// <returns></returns> public string GetNormalMethod_2() { Hom

  • c# 反射+自定义特性保存数据至本地

    最近在项目过程中遇到了保存数据的需求,对实体类的部分数据进行保存,打算采用反射+自定义特性来实现数据保存,利于扩展 1. 采用反射实现能够灵活获取要保存的数据,由于只需要保存实体类(Model)的部分数据,因此采用自定义特性标记需要保存的数据,同时数据要求以.csv格式保存,添加自定义特性有利于对表头进行描述 2. 实现自定义特性 public class ResultAttribute : Attribute { private bool _IsSave; /// <summary> ///

  • 关于C#反射 你需要知道的

    通常,反射用于动态获取对象的类型.属性和方法等信息.今天带你玩转反射,来汇总一下反射的各种常见操作,捡漏看看有没有你不知道的. 获取类型的成员 Type 类的 GetMembers 方法用来获取该类型的所有成员,包括方法和属性,可通过 BindingFlags 标志来筛选这些成员. using System; using System.Reflection; using System.Linq; public class Program { public static voidMain() {

  • C#基于Linq和反射实现数据持久化框架Xml4DB详解

    我们知道目前大部分的数据库都是关系型数据库, 所谓关系型数据库,就是指建立在关系模型 基础之上的数据库系统,如Oracle.SQL Server.Access.MySQL等.关系模型就是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织.一个偶然的机会我接触到了DB4O,它是一个完全面向对象的开源数据库,它的出现完全颠覆了传统的数据库在人们心中的形象,因为传统的数据库需要在数据体.实体之间转换,而且需要映射文件提供映射关系.正是这个项目让我产生了编写Xml4DB的想

  • .NET/C#如何使用反射注册事件详解

    前言 通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的名称.限定符和参数等.有了反射,即可对每一个类型了如指掌.如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道.那么如何注册事件呢? 本文将介绍如何使用反射注册事件.下面话不多说了,来一起看看看详细的介绍吧 不使用反射 例如,我们希望反射的类型是这样的: public class Walterlv { public e

  • C#使用反射(Reflect)获取dll文件中的类型并调用方法

    使用反射(Reflect)获取dll文件中的类型并调用方法,具体内容如下 需引用:System.Reflection; 1. 使用反射(Reflect)获取dll文件中的类型并调用方法(入门案例) static void Main(string[] args) { //dll文件路径 string path = @"D:\VS2015Project\001\Computer\bin\Debug\computer.dll"; //加载dll文件 Assembly asm = Assemb

  • C# 通过反射获取类型的字段值及给字段赋值的操作

    举例: 存在一个类: Public Class Student { public string name; public int age; } Student stu1 = new Student(); 现在,我们想通过反射在运行时给stu1的name 和 age字段 赋值,让name = "小明",age = 15,怎么做? 简单的代码如下: ...略 using System.Reflection;//反射类 ...略 static void Main(string[] args)

  • c#使用dynamic类型优化反射的方法

    什么是dynamic类型? 微软给出的官方文档中这样解释:在通过 dynamic 类型实现的操作中,该类型的作用是绕过编译时类型检查. 改为在运行时解析这些操作. dynamic 类型简化了对 COM API(例如 Office Automation API).动态 API(例如 IronPython 库)和 HTML 文档对象模型 (DOM) 的访问.在大多数情况下,dynamic 类型与 object 类型的行为类似. 但是,如果操作包含 dynamic 类型的表达式,那么不会通过编译器对该

  • 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(stri

  • dotNet中的反射用法入门教程

    本文实例讲述了dotNet中的反射用法.分享给大家供大家参考,具体如下: 参考MSDN: ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpcondiscoveringtypeinformationatruntime.htm 提纲: 1. 什么是反射 2. 命名空间与装配件的关系 3. 运行期得到类型信息有什么用 4. 如何使用反射获取类型 5. 如何根据类型来动态创建对象 6. 如何获取方法以及动态调用方法 7. 动态创

  • java数组复制的四种方法效率对比

    有关数组的基础知识,有很多方面,比方说初始化,引用,遍历,以及一维数组和二维数组,今天我们先看看数组复制的有关内容. 来源于牛客网的一道选择题: JAVA语言的下面几种数组复制方法中,哪个效率最高? A.for循环逐一复制 B.System.arraycopy C.System.copyof D.使用clone方法 效率:System.arraycopy>clone>Arrays.copyOf>for循环 1.System.arraycopy的用法: public static void

  • 关于Django ForeignKey 反向查询中filter和_set的效率对比详解

    前言 大家使用 Django 创建模型的时候一定会经常使用 ForeignKey 来创建两个表格之间多对一的外键关系,例如B中有一个 models.ForeignKey(A) .而当我们需要反向查询 A 中某个具体实例所关联的 B 时,可能会用到 A.B_set.all() 或 B.objects.filter(A) 这两种不同的方法. 不知道大家有没有也想过一个问题:当网站实际上线后,SEO强调页面加载速度,而当面对不断增大的请求量,这两种方法的哪一种速度更快? 馆主我产生了这个疑问,所以就打

  • Django bulk_create()、update()与数据库事务的效率对比分析

    下面以创建10000个对象为例进行测试: # 用for循环挨个创建,共花费37秒 for i in range(10000): name="String number %s"%i Record.objects.create(name=name) # 用django事务只提交一次,共花费2.65秒 @transaction.commit_manually def manual_transaction(): for i in range(10000): name="String

  • JAVA编程不能不知道的反射用法总结

    目录 下面对Java反射的基础知识进行说明和总结: 总结 下面对Java反射的基础知识进行说明和总结: 首先定义一个MyBase类,其中有私有字段,也有公有字段.同时也有公有方法和私有方法.MyBase类示例如下: package com.hwdev.demo; /** * 基类示例 * @author wangming */ public class MyBase { //公有字段 public int version = 1; //私有字段 private String date = "20

  • python中反射用法实例

    本文实例讲述了python中反射用法.分享给大家供大家参考.具体如下: import sys, types,new def _get_mod(modulePath): try: aMod = sys.modules[modulePath] if not isinstance(aMod, types.ModuleType): raise KeyError except KeyError: # The last [''] is very important! aMod = __import__(mo

  • Go语言学习笔记之反射用法详解

    本文实例讲述了Go学习笔记之反射用法.分享给大家供大家参考,具体如下: 一.类型(Type) 反射(reflect)让我们能在运行期探知对象的类型信息和内存结构,这从一定程度上弥(mi)补了静态语言在动态行为上的不足.同时,反射还是实现元编程的重要手段. 和 C 数据结构一样,Go 对象头部并没有类型指针,通过其自身是无法在运行期获知任何类型相关信息的.反射操作所需要的全部信息都源自接口变量.接口变量除存储自身类型外,还会保存实际对象的类型数据. func TypeOf(i interface{

  • PHP遍历数组的三种方法及效率对比分析

    本文实例分析了PHP遍历数组的三种方法及效率对比.分享给大家供大家参考.具体分析如下: 今天有个朋友问我一个问题php遍历数组的方法,告诉她了几个.顺便写个文章总结下,如果总结不全还请朋友们指出 第一.foreach() foreach()是一个用来遍历数组中数据的最简单有效的方法. <?php $urls= array('aaa','bbb','ccc','ddd'); foreach ($urls as $url){ echo "This Site url is $url! <b

  • Python 多线程抓取图片效率对比

    目的: 是学习python 多线程的工作原理,及通过抓取400张图片这种IO密集型应用来查看多线程效率对比 import requests import urlparse import os import time import threading import Queue path = '/home/lidongwei/scrapy/owan_img_urls.txt' #path = '/home/lidongwei/scrapy/cc.txt' fetch_img_save_path =

随机推荐