我不是编译器优化专家。就编译器或优化而言,我甚至不确定什么是“合理的”。我只是好奇而且问问题都是。
无论如何,我正在编写一些基本形式的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.
他们不一样。如果我正确阅读(也许我不是),则不会执行优化。
我可以看到一些可能性:
可以执行优化,我只是不启用优化,因为我使用了错误的函数来编译,或者没有使用正确的标志等。
不执行优化。
其他
这是什么?
注意:请不要陷入困境,谈论“如果你使用案例陈述,你可以这样做”或“你可以通过做等等来避免这种情况”。关键在于测试erlang编译器执行或不执行哪些优化,以及为什么或为什么不执行。
感谢。
答案 0 :(得分:5)
你说得对 - Beam编译器没有做任何常见的子表达式消除。原因可能是在Erlang通常使用的那种程序中,这没有任何明显的效果,因此没有人愿意实现它。 (对于极少数计算密集型Erlang代码的情况,程序员通常很容易处理这个问题,就像你在第二个例子中所做的那样。)
如果您编译为本机代码,您可能会获得这种优化 - HiPE编译器会更加努力地生成良好的低级代码。