在这种情况下,哪种更好/优化的方式来声明和使用变量?
int i;
for(i = 0; i < 10; i++)
Console.WriteLine(i);
for(i = 0; i < 100; i++)
Console.WriteLine(i);
OR
for(int i = 0; i < 10; i++)
Console.WriteLine(i);
for(int i = 0; i < 100; i++)
Console.WriteLine(i);
答案 0 :(得分:5)
从表现的角度来看,这是无关紧要的。
首先,即使在第二个示例中,运行时重新使用单个变量的概率也相当高。
接下来,即使它没有,将额外的int分配给堆栈然后再回收它在性能上几乎没有任何成本。它使这种方法的内存占用量增加了4个字节;而已。如果这对您来说实际上是一个问题(即您的堆栈空间不足),那么您需要解决更大的问题,这不是合适的方法。它可能意味着你应该将递归函数转换为非递归函数。
您应该做任何您认为最易读或更容易编写的内容,并且最不可能导致错误或问题。对我而言,这几乎总是第二种情况,但如果您更喜欢写出第一种情况(并且您的团队对此感到满意)那么这完全取决于您,请记住,性能在这里完全不是因素。
答案 1 :(得分:1)
在某些情况下,您需要在for-loop ...
之外的计数器变量的值int i;
for (i = 0; i < N; i++) {
if (SomeCondition(i)) {
break;
}
}
DoSomeThingWith(i);
...然后你会在for循环之外声明它。在所有其他情况下,我会在for循环中声明它,因为它使这个变量的意图更清晰。
for (int i = 0; i < N; i++) {
...
}
这里很明显,这个变量在循环之外没有一个有意义的值(它的范围无论如何都限于循环)。很明显,它只会用于此迭代目的,而不会用于任何其他目的。
答案 2 :(得分:0)
如果您查看MSIL,您可以看到差异是变量声明:
.method public hidebysig static
void task1 () cil managed
{
.locals init (
[0] int32 i
)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: br.s IL_000e
.loop
{
IL_0004: ldloc.0
IL_0005: call void [mscorlib]System.Console::WriteLine(int32)
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: add
IL_000d: stloc.0
IL_000e: ldloc.0
IL_000f: ldc.i4.s 10
IL_0011: blt.s IL_0004
}
IL_0013: ldc.i4.0
IL_0014: stloc.0
IL_0015: br.s IL_0021
.loop
{
IL_0017: ldloc.0
IL_0018: call void [mscorlib]System.Console::WriteLine(int32)
IL_001d: ldloc.0
IL_001e: ldc.i4.1
IL_001f: add
IL_0020: stloc.0
IL_0021: ldloc.0
IL_0022: ldc.i4.s 100
IL_0024: blt.s IL_0017
}
IL_0026: ret
}
第二种情况:
.method public hidebysig static
void task2 () cil managed
{
.locals init (
[0] int32 i,
[1] int32 i
)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: br.s IL_000e
.loop
{
IL_0004: ldloc.0
IL_0005: call void [mscorlib]System.Console::WriteLine(int32)
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: add
IL_000d: stloc.0
IL_000e: ldloc.0
IL_000f: ldc.i4.s 10
IL_0011: blt.s IL_0004
}
IL_0013: ldc.i4.0
IL_0014: stloc.1
IL_0015: br.s IL_0021
.loop
{
IL_0017: ldloc.1
IL_0018: call void [mscorlib]System.Console::WriteLine(int32)
IL_001d: ldloc.1
IL_001e: ldc.i4.1
IL_001f: add
IL_0020: stloc.1
IL_0021: ldloc.1
IL_0022: ldc.i4.s 100
IL_0024: blt.s IL_0017
}
IL_0026: ret
}
区别是一个当地宣布的。并将其加载到内存中。在第一种情况下,它加载两次变量。