众所周知,C# 的反射性能开销相当大。以通过反射方式调用函数为例,相比直接调用,反射的性能损耗十分显著。

为了改善性能,可以借助 MethodInfo 创建 Delegate,再通过调用该 Delegate 来提升执行效率。

下面通过测试代码对比以下几种函数调用方式的性能消耗:

  1. 直接函数调用
  2. 通过 delegate 调用
  3. 通过反射调用
  4. 通过动态修改 IL 代码来加速调用(待尝试)
using System;
                using System.Reflection;
                using System.Diagnostics;
                
                namespace ConsoleApp2
                {
                    public delegate void VoidFuncVoid();
                    class Test
                    {
                        public void on_xxx()
                        {
                            float x = 100.0f;
                            x *= x * x * x * x * x * x * x;
                        }
                    }
                    class Program
                    {
                        static void Main(string[] args)
                        {
                
                            Test test = new Test();
                
                
                
                            var me = test.GetType().GetMethod("on_xxx");
                            var de = (VoidFuncVoid)me.CreateDelegate(typeof(VoidFuncVoid), test);
                
                
                            Stopwatch sw = new Stopwatch();
                            {
                                sw.Start();
                                for (int i = 0; i < 10000; i++)
                                {
                                    test.on_xxx();
                                }
                                sw.Stop();
                                Console.WriteLine("call method with direct " + sw.ElapsedTicks);
                                sw.Reset();
                            }
                            {
                                sw.Start();
                                for (int i = 0; i < 10000; i++)
                                {
                                    de();
                                }
                                sw.Stop();
                                Console.WriteLine("call method with delegate " + sw.ElapsedTicks);
                                sw.Reset();
                            }
                            {
                                sw.Start();
                                for (int i = 0; i < 10000; i++)
                                {
                                    me.Invoke(test, null);
                                }
                                sw.Stop();
                                Console.WriteLine("call method with reflection " + sw.ElapsedTicks);
                                sw.Reset();
                            }
                            Console.ReadKey();
                        }
                    }
                }
                

输出结果如下:

总结:通过 delegate 调用的性能开销最小,甚至优于直接调用函数。