C# 这些操作是否等效?
我正在重构一些代码,我偶然发现了这样一段话C# 这些操作是否等效?,c#,algorithm,C#,Algorithm,我正在重构一些代码,我偶然发现了这样一段话 if (a > 1.0) a = 1.0; else if (a < -1.0) a = -1.0; if (Math.Abs(a) > 1.0) a = a < 0 ? -1.0 : 1.0; if(a>1.0) a=1.0; 否则如果(a1.0) a=a1.0) a=1.0; 否则如果(a1.0) a=a1.0) 000000 2B fld qword ptr[ebp+8] 0000002e fld1 000
if (a > 1.0)
a = 1.0;
else if (a < -1.0)
a = -1.0;
if (Math.Abs(a) > 1.0)
a = a < 0 ? -1.0 : 1.0;
if(a>1.0)
a=1.0;
否则如果(a<-1.0)
a=-1.0;
根据我们的指导原则,我应该把它重构成这样的东西
if (a > 1.0)
a = 1.0;
else if (a < -1.0)
a = -1.0;
if (Math.Abs(a) > 1.0)
a = a < 0 ? -1.0 : 1.0;
if(数学Abs(a)>1.0)
a=a<0-1.0 : 1.0;
当然,只有在不改变语句逻辑的情况下才允许重构。我已经看完了,没有发现任何偏差或差异。我还编写并运行了一系列测试,试图找出那些棘手而尖锐的案例。一切似乎都很好
然后,一位同事在工作时偷看了一眼,用一种非常毒的语气暗示说那里有东西痒。他本来应该在第二天透露这个大秘密的,但后来他生病了,现在正在度假
几天来我一直在盯着这些线看。我睡过了。我已经试过了所有的窍门。没有什么!所以要么我没本事看,要么他就是个耍恶作剧的混蛋。我需要帮助确定。是的,它们是一样的Update:但不能使用大小写
Int.MinValue
\Long.MinValue
等,因为Math.Abs
会抛出一个溢出异常
-谢谢@SledgeHammer/@Quantic!-所以这可能就是问题所在
方法相同的“证明”(减去溢出)
这与:(写出Math.Abs
)
删除死代码:
if (a > 1.0)
{
if (a >= 0) //else
{
a = 1.0;
}
}
else if (a < -1.0)
{
if (a < 0)
{
a = -1.0;
}
}
完成:)
PS:为了便于阅读,如果愿意:
if (a > 1.0)
a = 1.0;
else if (a < -1.0)
a = -1.0;
Math.Abs(a)
相当于(参见)
同
if (a >= 0)
{
return a;
}
else
{
return -a;
}
因此,增加了以下条件:
if (a >= 0)
{
return a > 1.0;
}
else
{
return (-a) > 1.0;
}
if (a >= 0)
{
return a > 1.0;
}
else
{
return a < -1.0;
}
重写条件:
if (a >= 0)
{
return a > 1.0;
}
else
{
return (-a) > 1.0;
}
if (a >= 0)
{
return a > 1.0;
}
else
{
return a < -1.0;
}
是的,它们是一样的Update:但不能使用大小写
Int.MinValue
\Long.MinValue
等,因为Math.Abs
会抛出一个溢出异常
-谢谢@SledgeHammer/@Quantic!-所以这可能就是问题所在
方法相同的“证明”(减去溢出)
这与:(写出Math.Abs
)
删除死代码:
if (a > 1.0)
{
if (a >= 0) //else
{
a = 1.0;
}
}
else if (a < -1.0)
{
if (a < 0)
{
a = -1.0;
}
}
完成:)
PS:为了便于阅读,如果愿意:
if (a > 1.0)
a = 1.0;
else if (a < -1.0)
a = -1.0;
Math.Abs(a)
相当于(参见)
同
if (a >= 0)
{
return a;
}
else
{
return -a;
}
因此,增加了以下条件:
if (a >= 0)
{
return a > 1.0;
}
else
{
return (-a) > 1.0;
}
if (a >= 0)
{
return a > 1.0;
}
else
{
return a < -1.0;
}
重写条件:
if (a >= 0)
{
return a > 1.0;
}
else
{
return (-a) > 1.0;
}
if (a >= 0)
{
return a > 1.0;
}
else
{
return a < -1.0;
}
说明了为什么它们在概念上是相同的,所以我将深入研究它们的内部
我编写了一个小测试程序,然后查看了反汇编(Visual Studio 2012)
类程序
{
静态空隙A(双A)
{
如果(a>1.0)
a=1.0;
否则如果(a<-1.0)
a=-1.0;
}
静态空隙B(双a)
{
如果(数学Abs(a)>1.0)
a=a<0?-1.0:1.0;
}
静态void Main(字符串[]参数)
{
A(-1.17);
B(-1.17);
}
}
A的结果
if (a > 1.0)
0000002b fld qword ptr [ebp+8]
0000002e fld1
00000030 fcomip st,st(1)
00000032 fstp st(0)
00000034 jp 0000003A
00000036 jb 0000003E
00000038 jmp 0000003A
0000003a xor eax,eax
0000003c jmp 00000043
0000003e mov eax,1
00000043 test eax,eax
00000045 sete al
00000048 movzx eax,al
0000004b mov dword ptr [ebp-3Ch],eax
0000004e cmp dword ptr [ebp-3Ch],0
00000052 jne 0000005C
a = 1.0;
00000054 fld1
00000056 fstp qword ptr [ebp+8]
00000059 nop
0000005a jmp 00000092
else if (a < -1.0)
0000005c fld qword ptr [ebp+8]
0000005f fld dword ptr ds:[001D2F50h]
00000065 fcomip st,st(1)
00000067 fstp st(0)
00000069 jp 0000006F
0000006b ja 00000073
0000006d jmp 0000006F
0000006f xor eax,eax
00000071 jmp 00000078
00000073 mov eax,1
00000078 test eax,eax
0000007a sete al
0000007d movzx eax,al
00000080 mov dword ptr [ebp-3Ch],eax
00000083 cmp dword ptr [ebp-3Ch],0
00000087 jne 00000092
a = -1.0;
00000089 fld dword ptr ds:[001D2F58h]
0000008f fstp qword ptr [ebp+8]
if(a>1.0)
000000 2B fld qword ptr[ebp+8]
0000002e fld1
000000 30 fcomip街,街(1)
00000032 fstp st(0)
00000034日元0000003A
000000 36 jb 000000 3E
000000 38 jmp 000000 3A
0000003a异或eax,eax
000000 3C jmp 000000 43
0000003e mov eax,1
00000043测试eax,eax
00000045塞特艾尔
000000 48 movzx eax,al
000000 4B mov dword ptr[ebp-3Ch],eax
0000004e cmp dword ptr[ebp-3Ch],0
00000052 jne 0000005C
a=1.0;
00000054 fld1
00000056 fstp qword ptr[ebp+8]
00000059无
000000 5A jmp 000000 92
否则如果(a<-1.0)
000000 5C fld qword ptr[ebp+8]
000000 5F fld dword ptr ds:[001D2F50h]
00000065 fcomip街,街(1)
00000067 fstp st(0)
00000069JP0000006F
0000006b ja 00000073
0000006d jmp 0000006F
0000006f异或eax,eax
000000 71 jmp 000000 78
00000073 mov eax,1
00000078测试eax,eax
0000007a塞特艾尔
000000 7D movzx eax,al
000000 80 mov德沃德ptr[ebp-3Ch],eax
000000 83 cmp dword ptr[ebp-3Ch],0
00000087 jne 00000092
a=-1.0;
000000 89 fld dword ptr ds:[001D2F58h]
000000 8F fstp qword ptr[ebp+8]
总数:38项指示
B的结果
if (Math.Abs(a) > 1.0)
0000002b fld qword ptr [ebp+8]
0000002e sub esp,8
00000031 fstp qword ptr [esp]
00000034 call 749B481F
00000039 fstp qword ptr [ebp-44h]
0000003c fld qword ptr [ebp-44h]
0000003f fld1
00000041 fcomip st,st(1)
00000043 fstp st(0)
00000045 jp 0000004B
00000047 jb 0000004F
00000049 jmp 0000004B
0000004b xor eax,eax
0000004d jmp 00000054
0000004f mov eax,1
00000054 test eax,eax
00000056 sete al
00000059 movzx eax,al
0000005c mov dword ptr [ebp-3Ch],eax
0000005f cmp dword ptr [ebp-3Ch],0
00000063 jne 0000008A
a = a < 0 ? -1.0 : 1.0;
00000065 fld qword ptr [ebp+8]
00000068 fldz
0000006a fcomip st,st(1)
0000006c fstp st(0)
0000006e jp 00000072
00000070 ja 0000007A
00000072 nop
00000073 fld1
00000075 fstp qword ptr [ebp-4Ch]
00000078 jmp 00000083
0000007a fld dword ptr ds:[001D3008h]
00000080 fstp qword ptr [ebp-4Ch]
00000083 nop
00000084 fld qword ptr [ebp-4Ch]
00000087 fstp qword ptr [ebp+8]
if(数学Abs(a)>1.0)
000000 2B fld qword ptr[ebp+8]
000000 2E子esp,8
000000 31 fstp qword ptr[esp]
00000034呼叫749B481F
000000 39 fstp qword ptr[ebp-44h]
000000 3C fld qword ptr[ebp-44h]
0000003f fld1
000000 41 fcomip街,街(1)
000000 43 fstp st(0)
000000 45日元000000 4b
000000 47 jb 000000 4F
000000 49 jmp 000000 4B
0000004b异或eax,eax
000000 4D jmp 000000 54
000000 4F mov eax,1
00000054测试eax,eax
00000056塞特艾尔
000000 59 movzx eax,al
000000 5C mov dword ptr[ebp-3Ch],eax
000000 5F cmp dword ptr[ebp-3Ch],0
00000063 jne 0000008A
a=a<0-1.0 : 1.0;
000000 65 fld qword ptr[ebp+8]
00000068 fldz
000000 6A fcomip街,街(1)
000000 6C fstp st(0)
0000006e日元00000072
00000070ja0000007a
00000072无
00000073 fld1
00000075 fstp qword ptr[ebp-4Ch]
00000078 jmp 00000083
000000 7A fld dword ptr ds:[001D3008h]
000000 80 fstp qword ptr[ebp-4Ch]
00000083无
000000 84 fld qword ptr[ebp-4Ch]
00000087 fstp qword ptr[ebp+8]
总计:36条指令+对Math.Abs的函数调用
结果:
第一个可能要快一点,但它们的大小非常接近,很难想象使用一个而不是另一个会严重影响性能。我个人同意你的评论,你的原始版本在概念上更容易理解
编辑<