C# S=(A+B)*(A+B)和C=A+B,S=C*C那种方式计算效率高

问题描述:

C# S=(A+B)*(A+B)和C=A+B,S=C*C那种方式计算效率高
如题

貌似是前者 


return (a+b)*(a+b)

.method public hidebysig instance int32 Calc1(int32 a, int32 b) cil managed
{
    .maxstack 8
    L_0000: ldarg.1 
    L_0001: ldarg.2 
    L_0002: add 
    L_0003: ldarg.1 
    L_0004: ldarg.2 
    L_0005: add 
    L_0006: mul 
    L_0007: ret 
}

c=a+b; return c*c;

.method public hidebysig instance int32 Calc2(int32 a, int32 b) cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 c)
    L_0000: ldarg.1 
    L_0001: ldarg.2 
    L_0002: add 
    L_0003: stloc.0 
    L_0004: ldloc.0 
    L_0005: ldloc.0 
    L_0006: mul 
    L_0007: ret 
}

IL指令都是8条 不过 JIT的反汇编差别就很大了

    20:             return (a + b) * (a + b);
00000000 55                   push        ebp 
00000001 8B EC                mov         ebp,esp 
00000003 83 EC 08             sub         esp,8 
00000006 89 4D FC             mov         dword ptr [ebp-4],ecx 
00000009 89 55 F8             mov         dword ptr [ebp-8],edx 
0000000c 83 3D 34 14 AD 03 00 cmp         dword ptr ds:[03AD1434h],0 
00000013 74 05                je          0000001A 
00000015 E8 79 4E 35 76       call        76354E93 
0000001a 8B 45 F8             mov         eax,dword ptr [ebp-8] 
0000001d 03 45 08             add         eax,dword ptr [ebp+8] 
00000020 8B 55 F8             mov         edx,dword ptr [ebp-8] 
00000023 03 55 08             add         edx,dword ptr [ebp+8] 
00000026 0F AF C2             imul        eax,edx 
00000029 8B E5                mov         esp,ebp 
0000002b 5D                   pop         ebp 
0000002c C2 04 00             ret         4

它很主动的用edx去保存临时结果...orz

    25:             int c = a + b;
00000000 55                   push        ebp 
00000001 8B EC                mov         ebp,esp 
00000003 83 EC 0C             sub         esp,0Ch 
00000006 89 4D FC             mov         dword ptr [ebp-4],ecx 
00000009 89 55 F8             mov         dword ptr [ebp-8],edx 
0000000c 83 3D 34 14 AD 03 00 cmp         dword ptr ds:[03AD1434h],0 
00000013 74 05                je          0000001A 
00000015 E8 39 4E 35 76       call        76354E53 
0000001a 33 D2                xor         edx,edx 
0000001c 89 55 F4             mov         dword ptr [ebp-0Ch],edx 
0000001f 8B 45 F8             mov         eax,dword ptr [ebp-8] 
00000022 03 45 08             add         eax,dword ptr [ebp+8] 
00000025 89 45 F4             mov         dword ptr [ebp-0Ch],eax 
    26:             return c * c;
00000028 8B 45 F4             mov         eax,dword ptr [ebp-0Ch] 
0000002b 0F AF 45 F4          imul        eax,dword ptr [ebp-0Ch] 
0000002f 8B E5                mov         esp,ebp 
00000031 5D                   pop         ebp 
00000032 C2 04 00             ret         4

计算出a+b后又扔回了内存  就显得重复了..能直接mov到edx应该就和上面一样了...

中间两句编译的也很奇怪...先对edx清0然后再mov回栈区  其实执行的是c=0初始化..

.net的安全性要求使得效率略微有些降低


以上调试环境 vs10 .net4 consoleApp release   CPU是桌面版i3