Optimization “如何优化表单的语句”;if(A==B){…}else如果(A<;B){…}else{…}”;

Optimization “如何优化表单的语句”;if(A==B){…}else如果(A<;B){…}else{…}”;,optimization,premature-optimization,Optimization,Premature Optimization,我有一段代码,就像 if (A == B) { ... } else if (A < B) { ... } else // (A > B) { ... } if(A==B) { ... } 否则如果(AB) { ... } 我意识到存在冗余问题,因为在计算==和时会有一些相同的位比较。您没有指定语言,但根据语言的不同,可以通过多种方式重写 Ruby方式(使用): 案例A和案例B 当-1那么…#AB 结束 ,和Groovy也有相同的运算符。许多其他语言具

我有一段代码,就像

if (A == B)
{
    ...
}
else if (A < B)
{
    ... 
}
else // (A > B)
{
    ...
}
if(A==B)
{
...
}
否则如果(AB)
{
...
}

我意识到存在冗余问题,因为在计算
==
时会有一些相同的位比较。您没有指定语言,但根据语言的不同,可以通过多种方式重写

Ruby方式(使用):

案例A和案例B
当-1那么…#AB
结束
,和Groovy也有相同的运算符。许多其他语言具有类似的运算符或函数,用于相同的组合比较目的,如。C#没有该运算符,但它有
i可比较
接口,与
CompareTo
方法相匹配

VB方式:

选择案例A
病例B
...
结束选择
在C++、C++和许多类似C语言的语言中,没有<代码> Cuto to < /C> >方法,可以使用这种方式< /P>
intcmp=(A>B)-(A
许多语言(如Java)不允许您直接将比较结果用作数值。在这种情况下,您可以使用

开关(整数符号(A-B))

在C和C++中,可以很容易地实现<代码>符号> /COD>函数 这些是用于高级语言的。在汇编级别,事情更简单。在x86汇编中,只需要一次比较,然后根据结果我们将跳转到相应的块,因此它是而不是3次比较,并且编译器足够聪明,可以优化这个简单的情况。例如:

    cmp eax, ebx
    je EQUAL_TO      ; jump if =
    ja GREATER_THAN  ; jump if >

    ; less than case's code
    jmp END_CMP

EQUAL_TO:
    ; equal case's code
    jmp END_CMP

GREATER_THAN:
    ; larger than case's code

END_CMP:
与其他具有比较标志(如ARM或68k)的体系结构相同。。。对于没有像MIPS这样标志的体系结构,您可能需要再进行一次比较,但决不需要进行三次比较

MIPS示例:

beq$t0,$t1,等于#$t0=A,$t1=B;如果($t0==$t1)等于();
slt$t0、$t1、$t2#$t2=小于=($t0<$t1);
beq$t2,$零,大于,如果(!小于)大于();
#“小于”代码在这里
# ...
j END_CMP
等于:
#“平等”代码
# ...
j END_CMP
大于:
#“较大”代码
# ...
完:
对于具有条件指令(如ARM或安腾)的体系结构,以及在if-else块中具有足够简单的主体的体系结构,对于C#甚至可能不需要跳转

;您可以使用接受2个值的通用函数,然后针对每种情况使用lambda操作

void CompareAndAct(T a,T b,Action fnEqualTo,Action fnLessThan,Action fngreater than){
var comparison=System.Collections.Generic.comparier.Default.Compare(a,b);
如果(比较==0){
fnEqualTo();
}
否则如果(比较<0){
fnLessThan();
}
else{//A>B
fn大于();
}
}
然后,您可以根据需要重复使用它,如下所示:

CompareAndAct(a,b,()=>Console.Writeline(“等于”),()=>Console.Writeline(“小于”),()=>Console.Writeline(“大于”);

我不能说我会推荐这样做,但它会起作用。它不会更快(或者更慢),但我想有人会说它是“更花哨的”

分支预测将影响到它的运行速度,而不仅仅是最小化一次比较。除此之外,这确实是一个过早的优化,如果你的逻辑中有3种不同的
,==
行为,你应该使用你描述的3种条件,使其可读。我认为你应该更改你的用户名ld知道解决方案:-)一些语言可能会为汇编提供一个很好的答案,尽管在测试了equal和above/greater之后,剩下的都是Lower/less,因此不需要自己进行测试-如OP的示例所示。这就是gcc和其他编译器将要做的。在调试生成的代码时,您可能会显式执行两个测试:比较和全部。OP的代码可能(在某种程度上)经过优化,首先测试最常见/时间关键的情况,然后转向越来越不常见/时间关键的变体。