2012-09-13 68 views
1

代數表達式讓我們考慮定義的函數如下:在編譯時產生的d

f(n, x) = F(n, x, f(n-1, x)) 
f(0, x) = g(x) 

在我的計劃中n值始終在編譯時已知。我想優化我的程序並避免循環或遞歸調用此函數。應該在編譯時生成f(n, x)的整個表達式,以便編譯器優化它。

直接解決方法是「手動」生成包含此表達式的字符串並使用mixin語句。我不喜歡這種方式。

編譯器能夠/應該展開已知深度的遞歸嗎?

I.e.將下面的函數的方式進行優化,我想:

double f(uint n)(double x) 
{ 
    static if(n == 0) 
     return g(x); 
    else 
     return F(n, x, f!(n-1)(x)); 
} 

回答

3

有對語言規範的優化沒有保證據我所知。雖然你的例子看起來很適合編譯器的優化。

簡單的實驗: 我寫了存根函數g()和F()來做一些簡單的計算。與 DMD-GC -O -inline」編譯經過與objdump的:

0000000000426860 <_Dmain>: 
    426860: 55      push %rbp 
    426861: 48 8b ec    mov %rsp,%rbp 
    426864: f2 48 0f 10 05 2b a7 rex.W movsd 0x2a72b(%rip),%xmm0  # 450f98 <_IO_stdin_used+0x38> 
    42686b: 02 00 
    42686d: be 0a 00 00 00   mov $0xa,%esi 
    426872: 48 bf 28 10 66 00 00 movabs $0x661028,%rdi 
    426879: 00 00 00 
    42687c: e8 6f 01 00 00   callq 4269f0 <_D3std5stdio4File14__T5writeTdTaZ5writeMFdaZv> 
    426881: 31 c0     xor %eax,%eax 
    426883: 5d      pop %rbp 
    426884: c3      retq 

正如你所看到的,一切竟是編譯期間計算,並與被立即打印作爲參數傳遞給writeln單一數值代替。我也檢查了x在運行時讀取的修改,並且沒有調用f()。ASM列表在這裏很長,所以我不會複製它

此外,如果您的參數已知編譯時,然後,可能,CTFE(編譯時功能評估)是一個更好的解決方案,因爲它是有保證的。