-3

我有一段代码就像

if (A == B)
{
    ...
}
else if (A < B)
{
    ... 
}
else // (A > B)
{
    ...
}

==我意识到存在冗余问题,因为在计算and时会有一些相同的位比较<。如何优化我的代码以使其更漂亮、更快?

4

2 回答 2

1

您没有指定语言,但取决于语言,这可以通过多种方式重写

Ruby方式(使用宇宙飞船运算符):

case A <=> B
    when -1 then... # A < B
    when  0 then... # A = B
    when  1 then... # A > B
end

PerlPHP7和 Groovy 也有相同的操作符。许多其他语言具有类似的运算符或函数,用于相同的组合比较目的cmp,例如 Python 2、compareOCaml 和compareToKotlin。C# 没有那个运算符,但它有方法的IComparable接口CompareTo

VB方式:

Select Case A
    Case Is < B
        ...
    Case Is = B
        ...
    Case Is > B
        ...
End Select

在 C、C++ 和许多没有CompareTo方法的类 C 语言中,您可以使用这种方式

int cmp = (A > B) - (A < B);
switch (cmp)
{
    case -1: ...
    case  0: ...
    case  1; ...
}

许多语言(如 Java)不允许您直接将比较结果用作数值。在这种情况下,您可以使用该signum功能

switch(Integer.signum(A - B))

您可以像这样signum在 C 和 C++ 中轻松实现函数

这些是针对高级语言的。在装配级别,事情更简单。在 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 示例:

    beq $t0, $t1, EQUAL_TO       # $t0 = A, $t1 = B; if ($t0 == $t1) equal();
    slt $t0, $t1, $t2            # $t2 = is_less_than = ($t0 < $t1);
    beq $t2, $zero, GREATER_THAN # if (!is_less_than) larger();

    # "less than" code here
    # ...
    j END_CMP

EQUAL_TO:
    # "equal" code
    # ...
    j END_CMP

GREATER_THAN:
    # "larger" code
    # ...

END_CMP:

对于具有条件指令(如 ARM 或 Itanium)且 if-else 块中的主体足够简单的架构,您甚至可能不需要跳转

于 2014-05-28T18:46:40.110 回答
0

对于 C#,您可以使用接受 2 个值的通用函数,然后为每种情况使用一个 lambda 操作。

void CompareAndAct<T>(T a, T b, Action fnEqualTo, Action fnLessThan, Action fnGreaterThan)  {

   var comparison = System.Collections.Generic.Comparer<T>.Default.Compare(a, b);
   if (comparison == 0) {
      fnEqualTo();
   }
   else if (comparison < 0) {
      fnLessThan();
   }
   else {  //A > B
      fnGreaterThan();
   }
}

然后你可以像这样重复使用它:

CompareAndAct(a,b, () => Console.Writeline("Equal"),() => Console.WriteLine("Less Than", () => Console.WriteLine("Greater Than"));

我不能说我会推荐这样做,但它会起作用。它没有更快(可能更慢),但我想有人可以说它“更高级”。

于 2014-05-28T19:03:14.463 回答