案例陈述的编译器优化

时间:2011-01-02 16:24:50

标签: string compiler-optimization case-statement

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

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

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

2 个答案:

答案 0 :(得分:0)

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

如果我正在编写自己的编译器并遇到如上所述的case语句,我可能会尝试对比较进行排序并进行二分查找以确定要采用的路径。这有望改善最坏情况。

答案 1 :(得分:0)

在C中,char数组(字符串)没有“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语句中的位移)是在编译时而不是运行时完成的,剩余的位移操作(交换机中的那个)相对便宜并且单个比较只需要一次(基本上不需要先放置最常见的路径)...对于匹配五个字符的情况,你可以为一个不常见的字符/字符添加一个额外的开关盒,或者只使用一个strcmp()。 ..但更好的是只需要几个案例的strcmp,而不是strcmp(){}的大型嵌套树,否则strcmp(){} else ...