4

可能重复:
在循环之前或循环中声明变量之间的区别?

我一直想知道,这样做是否更快:

int i;

for (i=0;i<...)
for (i=0;i<...)
for (i=0;i<...)
for (i=0;i<...)

或者

for (int i=0;i<...)
for (int i=0;i<...)
for (int i=0;i<...)
for (int i=0;i<...)

意思是,如果我在一个函数中有多个 for 循环,如果我声明一次循环迭代变量并多次使用它,或者在每个 for 循环中声明它,它会更快吗?

4

4 回答 4

4

对于这两种方法,生成的 IL(对于发布版本)几乎相同。

考虑这段代码:

static int test1()
{
    int result = 0;
    int i;

    for (i = 0; i < 10; ++i)
        ++result;

    for (i = 0; i < 10; ++i)
        ++result;

    return result;
}

static int test2()
{
    int result = 0;

    for (int i = 0; i < 10; ++i)
        ++result;

    for (int i = 0; i < 10; ++i)
        ++result;

    return result;
}

这将为发布版本生成以下 IL,我将其并排放置以便于比较:

test1():                        test2()
{                               {
    .maxstack 2                     .maxstack 2
    .locals init (                  .locals init (
        [0] int32 result,               [0] int32 result,
        [1] int32 i)                    [1] int32 i,
                                        [2] int32 V_2)
    L_0000: ldc.i4.0                L_0000: ldc.i4.0 
    L_0001: stloc.0                 L_0001: stloc.0 
    L_0002: ldc.i4.0                L_0002: ldc.i4.0 
    L_0003: stloc.1                 L_0003: stloc.1 
    L_0004: br.s L_000e             L_0004: br.s L_000e
    L_0006: ldloc.0                 L_0006: ldloc.0 
    L_0007: ldc.i4.1                L_0007: ldc.i4.1 
    L_0008: add                     L_0008: add 
    L_0009: stloc.0                 L_0009: stloc.0 
    L_000a: ldloc.1                 L_000a: ldloc.1 
    L_000b: ldc.i4.1                L_000b: ldc.i4.1 
    L_000c: add                     L_000c: add 
    L_000d: stloc.1                 L_000d: stloc.1 
    L_000e: ldloc.1                 L_000e: ldloc.1 
    L_000f: ldc.i4.s 10             L_000f: ldc.i4.s 10
    L_0011: blt.s L_0006            L_0011: blt.s L_0006
    L_0013: ldc.i4.0                L_0013: ldc.i4.0 
    L_0014: stloc.1                 L_0014: stloc.2 
    L_0015: br.s L_001f             L_0015: br.s L_001f
    L_0017: ldloc.0                 L_0017: ldloc.0 
    L_0018: ldc.i4.1                L_0018: ldc.i4.1 
    L_0019: add                     L_0019: add 
    L_001a: stloc.0                 L_001a: stloc.0 
    L_001b: ldloc.1                 L_001b: ldloc.2 
    L_001c: ldc.i4.1                L_001c: ldc.i4.1 
    L_001d: add                     L_001d: add 
    L_001e: stloc.1                 L_001e: stloc.2 
    L_001f: ldloc.1                 L_001f: ldloc.2 
    L_0020: ldc.i4.s 10             L_0020: ldc.i4.s 10
    L_0022: blt.s L_0017            L_0022: blt.s L_0017
    L_0024: ldloc.0                 L_0024: ldloc.0 
    L_0025: ret                     L_0025: ret 
}                               }

这清楚地表明您应该选择“i”是循环本地的版本,因为这是更好的做法。

但是,在循环外部声明循环计数器的版本将比将 int 初始化为零所需的时间更快 - 几乎可以忽略不计。

于 2012-04-27T09:07:06.410 回答
3

理论上前者应该更快,因为只有一个内存位置,可以重复使用。

于 2012-04-27T08:46:28.020 回答
1

正如spender所说,这里没有速度问题,更多的是与您需要变量可用的范围有关。如果它只需要在循环中可用,那么在循环中声明它而不是在它之外。但是,如果您需要所有循环都可以使用第一种方法,那么第一种方法会更快。

于 2012-04-27T08:48:45.570 回答
0

这两个代码产生相同的 JITted 代码。因此,它确实没有任何性能提升。

于 2012-04-27T09:03:55.177 回答