2012-02-08 134 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