c# 反射用法及效率對比
更新時間:2021年02月19日 11:52:17 作者:丹楓無跡
這篇文章主要介紹了c# 反射用法及效率對比,幫助大家更好的理解和學習使用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 { // 測試次數(shù) 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 { // 測試次數(shù) 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} - 使用反射創(chuàng)建出來的委托調用"); } 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# ListView 點擊表頭對數(shù)據(jù)進行排序功能的實現(xiàn)代碼
這篇文章主要介紹了C# ListView 點擊表頭對數(shù)據(jù)進行排序功能的實現(xiàn)代碼,需要的朋友可以參考下2017-04-04