在循环外移动变量声明是否真的会提高性能?

时间:2011-06-14 12:43:20

标签: c# performance variable-declaration

我正在编写非常耗费处理器的密码学代码(C#),所以我正在寻找任何性能提升,无论多小。我在这个问题上听到了双方的意见。

是否有任何性能优势

int smallPrime, spGen;

for (int i = 0; i < numSmallPrimes; i++)
{
    smallPrime = smallPrimes[i];
    spGen = spHexGen[i];

    [...]
}

这个?

for (int i = 0; i < numSmallPrimes; i++)
{
    int smallPrime = smallPrimes[i];
    int spGen = spHexGen[i];

    [...]
}

编译器是否已经这样做了?

2 个答案:

答案 0 :(得分:11)

根本没有性能优势。

在创建方法的堆栈帧时会分配所有局部变量,因此在声明它们的方法中无关紧要。它只是代码之间变量的范围,而且只是编译器在编译时使用的信息。

编辑:

为了验证没有区别,我编译了两个案例并检查了生成的机器代码,两种情况相同:

在循环外声明变量:

            for (int i = 0; i < numSmallPrimes; i++) {
00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  sub         esp,14h 
00000006  mov         dword ptr [ebp-4],ecx 
00000009  mov         dword ptr [ebp-14h],edx 
0000000c  cmp         dword ptr ds:[004214A8h],0 
00000013  je          0000001A 
00000015  call        69133CFB 
0000001a  xor         edx,edx 
0000001c  mov         dword ptr [ebp-10h],edx 
0000001f  xor         edx,edx 
00000021  mov         dword ptr [ebp-0Ch],edx 
00000024  xor         edx,edx 
00000026  mov         dword ptr [ebp-8],edx 
00000029  xor         edx,edx 
0000002b  mov         dword ptr [ebp-10h],edx 
0000002e  nop 
0000002f  jmp         0000006D 
                smallPrime = smallPrimes[i];
00000031  mov         eax,dword ptr [ebp-10h] 
00000034  mov         edx,dword ptr [ebp-14h] 
00000037  cmp         eax,dword ptr [edx+4] 
0000003a  jb          00000041 
0000003c  call        69136F00 
00000041  mov         eax,dword ptr [edx+eax*4+8] 
00000045  mov         dword ptr [ebp-8],eax 
                spGen = spHexGen[i];
00000048  mov         eax,dword ptr [ebp-10h] 
0000004b  mov         edx,dword ptr [ebp+8] 
0000004e  cmp         eax,dword ptr [edx+4] 
00000051  jb          00000058 
00000053  call        69136F00 
00000058  mov         eax,dword ptr [edx+eax*4+8] 
0000005c  mov         dword ptr [ebp-0Ch],eax 
                Console.WriteLine(smallPrime + spGen);
0000005f  mov         ecx,dword ptr [ebp-8] 
00000062  add         ecx,dword ptr [ebp-0Ch] 
00000065  call        68819C90 
            for (int i = 0; i < numSmallPrimes; i++) {
0000006a  inc         dword ptr [ebp-10h] 
0000006d  mov         eax,dword ptr [ebp-10h] 
00000070  cmp         eax,dword ptr [ebp-4] 
00000073  jl          00000031 
            }
        }
00000075  nop 
00000076  mov         esp,ebp 
00000078  pop         ebp 
00000079  ret         4

在循环中声明变量:

            for (int i = 0; i < numSmallPrimes; i++) {
00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  sub         esp,14h 
00000006  mov         dword ptr [ebp-4],ecx 
00000009  mov         dword ptr [ebp-14h],edx 
0000000c  cmp         dword ptr ds:[006314A8h],0 
00000013  je          0000001A 
00000015  call        68FB3C5B 
0000001a  xor         edx,edx 
0000001c  mov         dword ptr [ebp-8],edx 
0000001f  xor         edx,edx 
00000021  mov         dword ptr [ebp-0Ch],edx 
00000024  xor         edx,edx 
00000026  mov         dword ptr [ebp-10h],edx 
00000029  xor         edx,edx 
0000002b  mov         dword ptr [ebp-8],edx 
0000002e  nop 
0000002f  jmp         0000006D 
                int smallPrime = smallPrimes[i];
00000031  mov         eax,dword ptr [ebp-8] 
00000034  mov         edx,dword ptr [ebp-14h] 
00000037  cmp         eax,dword ptr [edx+4] 
0000003a  jb          00000041 
0000003c  call        68FB6E60 
00000041  mov         eax,dword ptr [edx+eax*4+8] 
00000045  mov         dword ptr [ebp-0Ch],eax 
                int spGen = spHexGen[i];
00000048  mov         eax,dword ptr [ebp-8] 
0000004b  mov         edx,dword ptr [ebp+8] 
0000004e  cmp         eax,dword ptr [edx+4] 
00000051  jb          00000058 
00000053  call        68FB6E60 
00000058  mov         eax,dword ptr [edx+eax*4+8] 
0000005c  mov         dword ptr [ebp-10h],eax 
                Console.WriteLine(smallPrime + spGen);
0000005f  mov         ecx,dword ptr [ebp-0Ch] 
00000062  add         ecx,dword ptr [ebp-10h] 
00000065  call        68699BF0 
            for (int i = 0; i < numSmallPrimes; i++) {
0000006a  inc         dword ptr [ebp-8] 
0000006d  mov         eax,dword ptr [ebp-8] 
00000070  cmp         eax,dword ptr [ebp-4] 
00000073  jl          00000031 
            }
        }
00000075  nop 
00000076  mov         esp,ebp 
00000078  pop         ebp 
00000079  ret         4

答案 1 :(得分:1)

不是真的,编译器会为你做优化。