2

我想拓宽我在编译器编写方面的知识和技能,尤其是优化方面。我想知道对于字符串类型的 case 表达式的 case 语句有哪些优化。例如在 Object Pascal 中:

ReadLn(s);
case s of
  'abc','def': ...;
  'xyz'      : ...;
  otherwise    ...;
end;

在 Free Pascal 中,这被转换为 AnsiCompareText 的后续调用。其他语言实现呢?我知道至少 PHP、Nimrod 和 Octave 支持这一点。

4

2 回答 2

0

作为应用程序开发人员,我希望将最有可能执行的案例放在首位,以限制比较的次数。不幸的是,从编译器的角度来看,直到运行时您才会知道这一点。

如果我正在编写自己的编译器并遇到像上面这样的 case 语句,我可能会尝试对比较进行排序并进行二进制搜索以确定采用哪条路径。这有望稍微改善最坏的情况。

于 2011-02-04T17:01:59.320 回答
0

在 C 中,char 数组(字符串)没有等效的“case”,但可以在某种程度上使用位移宏和 switch case 来完成

#define FIVE_CHARS(c1,c2,c3,c4,c5)  (((((((((c5)<<7)|(c4))<<6)|(c3))<<6)|(c2))<<6)|(c1))

while (argc-->0){
  switch ( FIVE_CHARS(argv[argc][0],argv[argc][1],argv[argc][2],argv[argc][3],argv[argc][4]) ){
     case FIVE_CHARS('-','h','e','l','p')  :
     case FIVE_CHARS('-','-','h','e','l')   :
     case FIVE_CHARS('-','h','\0','\0','\0')   :
     case FIVE_CHARS('-','?','\0','\0','\0')   :
       usage();
     break;
     case FIVE_CHARS('-','a','r','g','1')   :
       setflag1();
     break;
     default:
       assert("Argument not supported");
  }
}

编译器可能会将其编译为具有少量比较的一系列 if 或具有大量比较的跳转表。这可以显着提高代码大小和速度,因为大多数位移(在 case 语句中的位移)是在编译时而不是运行时完成的,其余位移操作(开关中的位移)相对便宜且一次比较只需要一次(基本上否定了将最常见的路径放在首位的任何需要)......对于匹配五个字符的情况,您可以为不常见的字符/字符添加额外的 switch case,或者只使用 strcmp() 。 .. 最好只在少数情况下需要 strcmp,而不是 if strcmp() {} else if strcmp() {} else ...

于 2012-04-12T04:28:21.790 回答