C#递归场景下局部函数性能是否低于普通函数?
C#递归局部函数性能低于实例方法的原因分析

你观测到的性能差异不是局部函数本身导致的,主要来源于局部函数捕获外部变量产生的闭包开销,具体原因如下:
- 闭包堆分配成本:你实现的局部函数
Next3捕获了外层方法的Process委托和当前实例this,C#编译器会为这类带变量捕获的局部函数生成隐藏的闭包类,每次调用Next2时都会在堆上实例化一个闭包对象存储捕获的变量,而普通实例方法Next不存在这部分额外的分配开销。 - 递归调用额外开销:带闭包的局部函数每次调用时都需要隐式传递闭包对象的引用作为参数,每一层递归调用都会比普通实例方法多一次参数传递和闭包字段访问的开销,在递归深度较高的场景下这部分开销会被放大。
- JIT优化限制:JIT编译器对普通类实例方法的内联、指令优化支持更成熟,而绑定了闭包上下文的局部函数可优化空间更小,进一步拉大了性能差距。
补充说明:如果局部函数没有捕获任何外层作用域的变量,其运行性能和普通静态/实例方法基本一致,不会产生额外资源消耗。
局部函数版本代码
internal void Next2(Action<int?> sProcess) { var Process = sProcess; Next3(this); #region Local func void Next3(Node L) { if (L.LeftChild == null && L.RightChild == null) { Process?.Invoke(this.Element); } else { if (L.LeftChild != null) { Next3(L.LeftChild); } if (L.RightChild != null) { Next3(L.RightChild); } } } #endregion }
非局部实例方法版本代码
internal void Next(Action<int?> Process) { if (LeftChild == null && RightChild == null) { Process?.Invoke(this.Element); } else { if (LeftChild != null) { this.LeftChild.Next(Process); } if (RightChild != null) { this.RightChild.Next(Process); } } }
内容的提问来源于stack exchange,提问作者Jianjie
相关产品推荐
相关产品推荐

