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# 反射用法及效率对比 的全部内容, 来源链接: utcz.com/z/335715.html

回到顶部