RT

解决方案 »

  1.   

    俩者效率差不多, 知识CASE 可读性更好
      

  2.   

    楼上和楼上的楼上和楼上的楼上的楼上 的理解能力有问题还是我表达能力不咋滴啊
    我的意思是
    Case 编译出来的机器码 比 If 编译的速度快吗?
      

  3.   

    具体要看情况,如果是简单的case语句,确实比if稍稍快一些,比如:case x of
      0: y := 1;
      1: y := 2;
      2: y := 3;
    end;case汇编代码大概是:  mov  eax, x
      sub  eax, 1
      jb   @@end   // 小于0退出
      jz   @@1     // 0
      dec  eax
      jz   @@2     // 1
      jmp  @@3     // 2
    @@1:
      mov  eax, 1
      jmp  @@4
    @@2:
      mov  eax, 2
      jmp  @@4
    @@3:
      mov  eax, 3
    @@4:
      mov  y, eax
    @@end:如果用if语句,汇编码大概是:
      mov  eax, x
      test eax, eax
      jnz  @@1
      mov  eax, 1
      jmp  @@3
    @@1:
      cmp  eax, 1
      jne  @@2
      mov  eax, 2
      jmp  @@3
    @@2:
      cmp  eax, 2
      jne  @@end
      mov  eax, 3
    @@3:
      mov  y, eax
    @@end:
    随手写的,不见得正确
      

  4.   

    翻一下历史贴子吧,其中对这个问题的说明已经足够多了。要去说明这个问题,需要把代码展开成为汇编指令才能够直观地表达出来。简单地说Delphi的CASE表达式,由于语法上的限制,而强制采用了常量比较,因此对于多分支的CASE表达式,则只需要一次计算,但是化作为if就有可能因为语法习惯性,导致多次运算。这些都是理论上的,需要根据具体的情况而定,比如if条件表达式只是一个单一条件表达式,那么编译器实际本身主可以通过优化机制做到最优。function Test(b: Boolean;a: Integer): integer;
    begin
      if b and (a=1) then begin
        result := 10;
      end else if b and (a=2) then begin
        result := 100;
      end else begin
        result := 1000;
      end;
    end;类似上面这样的代码,很明显第二个条件表示式当中的 b(=true)这个条件是可以与第一个条件合并掉的。如果你使用case表达式的话,则肯定会避免这样的问题,代码将会变成:
    function Test(b: Boolean;a: Integer): integer;
    begin
      Result := 1000;
      if Not b then Exit;
      case a of
        1:result := 10;
        2:result := 100;
      end;
    end;
    对于这样一段代码,所带来的效果,其实不尽其然,基本上可以忽略。但是如果是下面这样的代码,或许就会是非常有效的改善:
    function Test(b: Boolean;a: string): integer;
    begin
      if b and (a='1') then begin
        result := 10;
      end else if b and (a='2') then begin
        result := 100;
      end else begin
        result := 1000;
      end;
    end;比如优化一:
    function Test(b: Boolean;a: string): integer;
    begin
      Result := 1000;
      if Not b then Exit;
      case StrToIntDef(a,-1) of
        1: Result := 10;
        2: Result := 100;
      end;
    end;
    比如优化二:
    function Test(b: Boolean;a: string): integer;
    begin
      Result := 1000;
      if Not b then Exit;
      if Length(a) <> 1 then Exit;  case PAnsiChar(a)^ of
        '1': Result := 10;
        '2': Result := 100;
      end;
    end;当然这只是两个分支,并没有多少的意义。写代码本身也是仁者见仁智者见智的事情,每个程序或者设计者都会依据实际需要,权衡利弊做出不同的处理,比如说下面这段代码:
    function Test(b: Boolean;a: string): integer;
    begin
      if b and (a='abcd') then begin
        result := 10;
      end else if b and (a='xyz0') then begin
        result := 100;
      end else begin
        result := 1000;
      end;
    end;
    或者可以优化成:
    function Test(b: Boolean;a: string): integer;
    begin
      Result := 1000;
      if Not b then Exit;
      if Length(a) <> 4 then Exit;  case PAnsiChar(a)^ of
        $64636261 (*'abcd'*): Result := 10;
        $307a7978 (*'xyz0'*): Result := 100;
      end;
    end;在这个优化当中,只是假定了a的值有且只四个字符为必要分支条件的前提,如果再来些一个字符、两个字符,或许还稍好办一点,但要是三个呢?五个呢?处理起来就有可能有点不伦不类,至少增加了阅读的难度,或者需要修改原有的代码风格。代码优化始终是一个无止境的话题,优化除了性能优化,同时还有(目标代码)存储优化,甚至是执行需求优化等等,这几者之间甚或还有可能是一个个相互矛盾的关系,如何取舍对于设计者就有相当的考验。