首頁>Club>
影響效率的原因在於,[1。n] 這樣一個列表在FP語言裡,其中每一個元素都必須實實在在地被創建出來,在被sum消費完之後,又被GC掉。而實際上不停地對i自增再求和是可以完全不產生記憶體分配開銷的。
3
回覆列表
  • 1 # 碼農半生仍少年

    且不談FP,如果n是個常量,在C++裡可以寫個模板在編譯期直接搞定,算是最佳化到極致了吧。算是C++模板超程式設計(template meta-programming)技術的小試牛刀。

    template<int T> struct acc_ {

    enum { result = N + acc_<N - 1>::result };

    };

    template<> struct acc_<0> {

    enum { result = 0 };

    };

    使用:

    int sum = acc_<1234>::result;

    透過這種方式,acc_<1234>::result 會在編譯時直接被替換為常量,無任何執行時開銷。模板本身也不會產生任何額外二進位制程式碼。

    藉助boost裡的if_之類的,這個實現還能更簡單。

    當然,這個應該不是題主期望的答案,因為和FP無關。

    我不知道題主這裡說的FP語言具體指哪個,但是一般來講,這樣的求和,如果是遞迴求解的話,屬於尾遞迴呼叫,會被編譯器最佳化,不會導致任何額外的棧增長。n作為值型別,且是右值,往往是分配在棧上,而不是堆上,會隨著棧的增減快速清除,並不存在GC的問題。 比如erlang:

    acc(0) -> 0;

    acc(N) when N > 0 -> N + acc(N - 1);

    和C++模板的方式幾乎一模一樣(但這個是執行期求值),並不存在什麼儲存浪費和GC問題。

    所以,如果嚴格的談“編譯最佳化技術”,基於以上,可以總結出兩點:

    編譯期常量合併(constant folding, constant propagation);尾呼叫消除(tail-call elimination)。

    題外話,對於等差數列,可以直接用求和公式: f(n) = (1 + n) * n / 2

  • 中秋節和大豐收的關聯?
  • 語文教師如何才能在課前為同學們匯入知識點?