我应该使用嵌套块来提高性能

时间:2016-07-28 10:23:36

标签: .net stack

我一直在学习堆栈和堆,特别是堆栈及其LIFO方法。

这是否适用于方法中的嵌套块,并且可用于提高性能,例如

public void Test() {
    int i = 5;
    // do something with i

    int j = 5;
    // do something with j
}

在这个例子中,只有在方法结束时才能从堆栈中释放i和j。

以下会更有效吗? (我知道它的一个简单的程序.....)或者释放的努力是否会更多地节省堆栈的大小?

public void Test() {
    {
        int i = 5;
        // do something with i
    }
    {
        int j = 5;
        // do something with j
    }
}

这仅仅是为了示例目的,我知道我可以重构这个等等。我只对方法中的内存会发生什么感兴趣....

2 个答案:

答案 0 :(得分:5)

无论如何,堆栈都是为整个方法调用分配的。

一些微妙的情况,根据捕获的变量,添加额外的块可能有所帮助 - 如果你有两个lambda表达式,其中一个捕获i,其中一个捕获{ {1}},然后在你的第一种情况下,你最终得到一个合成类,它捕获两个变量,而在你的第二种情况下,你最终得到两个类......至少在当前实现中。

如果没有变量捕获,至少可能 JIT可能会注意到您一次只使用一个变量,并优化为两者重用相同的堆栈空间。

这样的微优化非常罕见,会对性能产生重大影响,但是它们可能会产生非常重要的可读性影响......所以我只会在以下情况下开始使代码的可读性降低: / p>

  • 您已经进行了强大的性能测试
  • 你有一个具体的表现目标(所以你知道什么时候完成)
  • 你缩小了瓶颈的范围
  • 您已经证明可读性的降低可以显着提升性能

答案 1 :(得分:0)

假设发布版本/配置,编译器(可能是JIT编译器而不是C#编译器)应该能够确定变量的生命周期不重叠,因此(如果它选择这样做)编译器可以重用相同的位置(实际上可能是寄存器而不是任何特定的堆栈空间)。

如果这些是引用,而且仍然假设发布,那么你的假设也不成立 - JIT和GC协作来理解变量的生命周期,因此可以在变量的同时收集对象引用它仍然是“在范围内”,只要该变量实际上不再被读取。