0

在这种情况下,声明和使用变量的更好/优化方式是什么?

int i;

for(i = 0; i < 10; i++)
    Console.WriteLine(i);

for(i = 0; i < 100; i++)
    Console.WriteLine(i);

或者

for(int i = 0; i < 10; i++)
    Console.WriteLine(i);

for(int i = 0; i < 100; i++)
    Console.WriteLine(i);
4

3 回答 3

5

从性能的角度来看,这无关紧要。

首先,即使在第二个示例中,运行时重用单个变量的可能性也相当高。

接下来,即使它没有,分配一个额外的 int 到堆栈,然后在稍后回收它实际上不会花费任何性能。它使该方法的内存占用增加了 4 个字节;而已。如果这对您来说确实是个问题(即您的堆栈空间不足),那么您需要解决更大的问题,而这不是解决问题的合适方法;这可能意味着您应该将递归函数转换为非递归函数。

你应该做任何你认为最易读或更容易编写并且最不可能导致错误或问题的事情。对我来说,这几乎总是第二种情况,但是如果您更喜欢写出第一种情况(并且您的团队对此表示同意),那么这完全取决于您,请记住,性能在这里完全不是因素。

于 2013-06-11T16:07:49.427 回答
1

在某些情况下,您需要在 for 循环之外使用 counter 变量的值...

int i;
for (i = 0; i < N; i++) {
    if (SomeCondition(i)) {
        break;
    }
}
DoSomeThingWith(i);

...然后你会在 for 循环之外声明它。在所有其他情况下,我会在 for 循环中声明它,因为它使这个变量的意图更加清晰。

for (int i = 0; i < N; i++) {
    ...
}

这里很明显,这个变量在循环之外不会有有意义的值(它的范围无论如何都限于循环)。同样清楚的是,它将仅用于此迭代目的,而不会用于其他目的。

于 2013-06-11T16:18:49.007 回答
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
}

不同之处在于一个本地声明。并将其加载到内存中。在第一种情况下,它两次加载变量。

于 2013-06-11T16:29:08.353 回答