在此方案中声明和使用变量的有效方法

时间:2013-06-11 16:04:12

标签: c# optimization coding-style

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

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);

3 个答案:

答案 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
}

区别是一个当地宣布的。并将其加载到内存中。在第一种情况下,它加载两次变量。