在循环之前或循环内声明变量的区别是什么?
在循环之前或循环内声明变量的区别是什么?
我一直在想,通常情况下,在循环之前声明一个临时变量,与在循环内部重复声明变量相比,是否会有任何(性能)差异?
以Java为例的一个(相当无意义的)例子:
a)循环之前的声明:
double intermediateResult; for(int i=0; i < 1000; i++){ intermediateResult = i; System.out.println(intermediateResult); }
b)循环内部(重复)声明:
for(int i=0; i < 1000; i++){ double intermediateResult = i; System.out.println(intermediateResult); }
哪个更好,a还是b?
我怀疑重复变量声明(示例b)在理论上会创建更多的开销,但编译器足够智能,所以这并不重要。示例b的优点是更紧凑,并将变量的作用域限制在其使用范围内。尽管如此,我倾向于按照示例a的编码方式。
编辑:我对Java的情况特别感兴趣。
在C#中,变量在循环内部声明或循环外部声明取决于语言版本和具体用途。在C# 1中,这没有任何区别。但是在C# 2中,如果局部变量被匿名方法(或C# 3中的lambda表达式)捕获,这可能会产生非常明显的区别。
下面是一个示例:
using System; using System.Collections.Generic; class Test { static void Main() { Listactions = new List (); int outer; for (int i = 0; i < 10; i++) { outer = i; int inner = i; actions.Add(() => Console.WriteLine("Inner={0}, Outer={1}", inner, outer)); } foreach (Action action in actions) { action(); } } }
输出结果如下:
Inner=0, Outer=9 Inner=1, Outer=9 Inner=2, Outer=9 Inner=3, Outer=9 Inner=4, Outer=9 Inner=5, Outer=9 Inner=6, Outer=9 Inner=7, Outer=9 Inner=8, Outer=9 Inner=9, Outer=9
可以看到,所有的操作都捕获了相同的`outer`变量,但每个操作都有自己独立的`inner`变量。
关于问题B(原始问题),每次循环是否实际上创建了一个新的变量?在堆栈中发生了什么?这在C# 1.0中是一个bug吗?理论上`Outer`不应该是9吗?
答案是:我不知道你的意思。lambda表达式在1.0中是不存在的...而且`Outer`确实是9。你指的是什么bug?
我的意思是在C# 1.0中,没有任何语言特性可以区分在循环内部声明变量和在循环外部声明变量(假设两者都能编译通过)。这在C# 2.0中发生了变化。没有bug。
哦,是的,我现在明白了,我完全忽视了在1.0中不能以那种方式闭包变量的事实,我的错!
声明变量是在循环之前还是在循环中的区别?这个问题的出现的原因是对于循环中变量声明的位置,不同的开发者有不同的观点和偏好,有人认为在循环之前声明变量可以提高性能,有人则认为在循环中声明变量更清晰简洁。为了解决这个问题,有人进行了实际的测试和性能分析。他们运行了两个例子A和B,每个例子循环执行1亿次,然后比较了它们的执行时间。结果表明,例子B稍微快一些。但是由于计算机的速度很快,很难准确地测量这种微小的差异。因此,无论是在循环之前还是在循环中声明变量,对于性能来说并没有太大的影响。然而,一些开发者认为在循环中声明变量可以减少变量在循环结束后的保持,从而节省内存。另外,还有一些开发者对于测试结果的可靠性提出了质疑,他们认为测试结果应该包含详细的测试设置和环境信息。这个问题的解决方法是根据具体情况选择合适的变量声明位置,并进行实际的测试和性能分析。