软件编程
位置:首页>> 软件编程>> C#编程>> c# 反射用法及效率对比

c# 反射用法及效率对比

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

标签: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");
 }
}

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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com