Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does moving variable declaration outside of a loop actually increase performance?

I'm writing very processor-intensive cryptography code (C#), so I'm looking for any performance gains, no matter how small. I've heard opinions both ways on this subject.

Is there any performance benefit at all to

int smallPrime, spGen;

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

    [...]
}

over this?

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

    [...]
}

Does the compiler do this already?

like image 588
jnm2 Avatar asked Jun 14 '11 12:06

jnm2


2 Answers

There is no performance benefit at all.

All local variables are allocated when the stack frame for the method is created, so it doesn't matter where in the method you declare them. It's only the scope of the variables that differ between the codes, and that is only information that the compiler uses at compile time.

Edit:

To verify that there is no difference, I compiled the two cases and examined the generated machine code, and it is identical for the two cases:

Declaring variables outside the loop:

            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

Declaring variables inside the loop:

            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
like image 57
Guffa Avatar answered Sep 18 '22 06:09

Guffa


Not really, the compiler will do that optimization for you.

like image 41
Jorge Córdoba Avatar answered Sep 19 '22 06:09

Jorge Córdoba