Erlang编译器优化

7

我并不是编译优化专家,甚至不确定针对编译器或优化方面有什么“合理”的期望。我只是好奇,并且只是在提问。

无论如何,我正在编写一些基本的 Erlang 代码,就像这样:

% 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编译器是否执行或不执行哪些优化,以及原因。
谢谢。
1个回答

5
您说得很对 - Beam编译器没有进行公共子表达式消除。原因可能是在Erlang通常用于的程序类型中,这没有任何明显的影响,所以没有人费心去实现它。(对于计算密集型的Erlang代码的罕见情况,程序员通常很容易处理这个问题,就像您在第二个示例中所做的一样。)
如果编译成本地代码,则可能会获得这种优化 - HiPE编译器会投入更多的精力来生成良好的低级别代码。

"公共子表达式消除" - 明白了。我知道我之前在哪里听过这个术语。我想我会手动优化大部分的东西,让 Erlang 优化一些处理递归等方面的内容。 - X Z

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接