2012-02-08 136 views
6

我没有编译器优化专家。我甚至不确定就编译器或优化而言期望什么是“合理”的。我只是好奇而问问题。二郎编译器优化

无论如何,我的基本形式编码了一些二郎神像这样:

% TOY EXAMPLE 1 
test(X) -> 
    if 
     X-1 > 0 -> 
      yes; 
     X-1 == 0 -> 
      maybe; 
     true -> no 
    end. 

然后然后我为了不要做两次减法优化它:

% TOY EXAMPLE 2 
test(X) -> 
    Z = X-1, 
    if 
     Z > 0 -> 
      yes; 
     Z == 0 -> 
      maybe; 
     true -> no 
    end. 

然后我认为“浪费时间 - 无论如何编译器都会优化第一个例子”。所以我决定通过运行带有'S'选项的compile:file来检查两者。这里输出:

% TOY EXAMPLE 1 
{function, test, 1, 15}. 
    {label,14}. 
    {func_info,{atom,exchange},{atom,test},1}. 
    {label,15}. 
    {gc_bif,'-',{f,16},1,[{x,0},{integer,1}],{x,1}}. 
    {test,is_lt,{f,16},[{integer,0},{x,1}]}. 
    {move,{atom,yes},{x,0}}. 
    return. 
    {label,16}. 
    {gc_bif,'-',{f,17},1,[{x,0},{integer,1}],{x,1}}. 
    {test,is_eq,{f,17},[{x,1},{integer,0}]}. 
    {move,{atom,maybe},{x,0}}. 
    return. 
    {label,17}. 
    {move,{atom,no},{x,0}}. 
    return. 

% TOY EXAMPLE 2 
{function, test, 1, 15}. 
    {label,14}. 
    {func_info,{atom,exchange},{atom,test},1}. 
    {label,15}. 
    {gc_bif,'-',{f,0},1,[{x,0},{integer,1}],{x,0}}. 
    {test,is_lt,{f,16},[{integer,0},{x,0}]}. 
    {move,{atom,yes},{x,0}}. 
    return. 
    {label,16}. 
    {test,is_eq,{f,17},[{x,0},{integer,0}]}. 
    {move,{atom,maybe},{x,0}}. 
    return. 
    {label,17}. 
    {move,{atom,no},{x,0}}. 
    return. 

他们是不一样的。如果我正在阅读这个权利(也许我没有),则不会执行优化。

我可以看到几种可能性:

  1. 可以进行优化,我只是没有因为我使用了错误的功能进行编译,或者没有使用正确的标志启用优化,等

  2. 优化只是不被执行。

  3. 其他。

这是什么?

注:请不要让她陷入了的说法:“如果你使用一个case语句,你可以做这样的,和这样的”或“你可以通过做夸夸其谈避免这种情况。”重点仅仅是测试erlang编译器做了哪些优化或不做什么,以及为什么或为什么不做。

谢谢。

回答

4

你说的很对 - 梁编译器不会做任何公共子表达式消除。原因可能是在Erlang通常用于的程序类型中,这不会有什么明显的效果,所以没有人会费心去实现它。 (对于罕见的计算密集型Erlang代码,程序员通常很容易处理此问题,就像您在第二个示例中那样)。

如果您编译为本地代码,则可能会得到这种优化 - HiPE编译器更加努力地生成良好的低级代码。

+0

“公共子表达式消除” - 得到了它。我知道我之前在某个地方听过这个词。我想我会手工优化大多数东西,让erlang优化一些处理递归的东西,而不是什么。 – 2012-02-09 06:30:56