有誰知道純功能編程而不是強制性編程(即容許反作用)發生時,最糟糕的漸近減速多是什麼? html
從itowlson的評論中澄清 :是否存在最知名的非破壞性算法比最知名的破壞性算法漸近惡化的問題? 算法
本文聲稱, 聯合查找算法的已知純功能實現都比它們發佈的算法具備更差的漸進複雜度,後者具備純功能接口,但內部使用可變數據。 編程
其餘答案聲稱永遠沒有任何區別,例如,純功能代碼的惟一「缺點」是它能夠並行化,這一事實使您對功能編程社區在這些問題上的瞭解程度/客觀性有所瞭解。 數組
編輯: 數據結構
下面的評論指出,對純函數式編程的優缺點的偏頗的討論可能不會來自「函數式編程社區」。 好點子。 也許我看到的倡導者只是在評論中說是「文盲」。 編程語言
例如,我認爲該博客文章是由能夠說是功能編程社區表明的人撰寫的,而且因爲它是「懶惰評估的要點」列表,所以,它是說起任何缺點的好地方懶惰和純函數式編程可能具備。 解僱如下人員是一個不錯的選擇(從技術上講是正確的,但偏向於不搞笑): 分佈式
若是嚴格函數在嚴格語言中具備O(f(n))複雜度,那麼在懶惰語言中函數也具備O(f(n))複雜性。 爲何要擔憂? :) 函數式編程
我建議閱讀Haskell的性能 ,而後看一下功能語言與程序/ OO語言的基準遊戲性能。 函數
根據Pippenger [1996]的研究 ,當將純功能的Lisp系統(具備嚴格的評估語義,而不是惰性的)與能夠變異數據的Lisp系統進行比較時,能夠翻譯爲在O( n )中運行的不純Lisp編寫的算法。轉換爲純Lisp中運行時間爲O( n log n )的算法(基於Ben-Amram和Galil [1992]關於僅使用指針模擬隨機存取存儲器的工做)。 皮蓬格(Pippenger)還肯定,有些算法是您能夠作的最好的。 在不純系統中存在O( n )在純系統中存在Ω( n log n )的問題。 性能
關於本文有一些警告。 最重要的是,它不解決惰性函數語言,例如Haskell。 Bird,Jones和De Moor [1997]證實由Pippenger構造的問題能夠在O( n )時間內以一種惰性函數語言解決,但它們並無肯定(據我所知,沒有人知道)是否沒有一種惰性函數語言能夠像變種語言同樣在相同的漸近運行時間內解決全部問題。
由皮蓬格(Pippenger)構造的問題須要專門構造Ω( n log n )才能得到此結果,而且不必定表明實際的實際問題。 對這個問題有一些限制,這是出乎意料的,可是對於證實工做是必不可少的。 特別地,該問題要求結果是在線計算的,而沒法訪問未來的輸入,而且輸入由來自無限可能原子集合的原子序列組成,而不是固定大小的集合。 而且本文僅針對線性運行時間的不純算法創建(下界)結果。 對於須要更長運行時間的問題,可能會在運行時間更長的算法所需的額外操做過程當中,「吸取」線性問題中出現的額外O(log n )因子。 Ben-Amram [1996]簡要地探討了這些澄清和開放性問題。
實際上,能夠用純功能語言以與具備可變數據結構的語言相同的效率來實現許多算法。 有關有效用於實現純功能數據結構的技術的良好參考,請參見Chris Okasaki的「純功能數據結構」 [Okasaki 1998] (這是其論文的擴展版本[Okasaki 1996] )。
任何須要在純功能數據結構上實現算法的人都應該閱讀Okasaki。 經過使用平衡的二叉樹模擬可變內存,您每次操做老是最糟糕的狀況是O(log n )變慢,可是在許多狀況下,您能夠作得更好,並且Okasaki描述了許多有用的技術,從攤銷技術到實物化,逐步進行攤銷的時間。 純功能數據結構可能很難使用和分析,可是它們提供了不少好處,例如引用透明性,有助於編譯器優化,並行和分佈式計算以及實現諸如版本控制,撤消和回滾之類的功能。
還要注意,全部這些僅討論漸近運行時間。 許多實現純功能數據結構的技術會給您必定程度的恆定因子減慢,這是因爲它們須要額外的簿記功能以及相關語言的實現細節。 純功能數據結構的好處可能賽過這些恆定因素的減速,所以您一般須要根據所討論的問題進行權衡。
在固定的內存使用上限上,應該沒有區別。
證實草圖:給定固定的內存使用上限,一我的應該可以編寫一臺虛擬機,該虛擬機以與您實際在該計算機上執行相同的漸進複雜度執行命令式指令集。 之因此這樣,是由於您能夠將可變內存做爲持久性數據結構進行管理,從而實現O(log(n))的讀寫,可是因爲內存使用量具備固定的上限,所以您能夠擁有固定的內存量,從而致使這些衰減到O(1)。 所以,功能實現能夠是在VM的功能實現中運行的命令式版本,所以它們都應具備相同的漸近複雜度。
確實有幾種算法和數據結構,即便是惰性的,也沒有已知的漸近有效的純函數解(在純lambda演算中能夠實現)。
可是,咱們假設在「命令式」語言中,對內存的訪問爲O(1),而在理論上不可能如此漸近(即對於無限制的問題大小),而且對龐大數據集中的內存的訪問始終爲O(log n) ,可使用功能語言進行仿真。
一樣,咱們必須記住,實際上全部現代功能語言都提供可變數據,Haskell甚至在不犧牲純度的狀況下提供了數據(ST monad)。