像什麼時候使用SPECIALIZE
編譯指示和它的性能增益。
如果您有一個(類型)多態函數,並且希望它經常在類的一個或幾個實例上調用,那麼讓編譯器專門化一個函數。
專業化將字典查找刪除使用的位置,並且通常可以進一步優化,類成員函數通常可以內聯,然後進行嚴格分析,兩者都可能帶來巨大的性能提升。如果唯一可能的優化是消除查詢,那麼收益一般不會很大。
由於GHC-7,它可能更有效地讓功能的{-# INLINABLE #-}
編譯,這使得在接口文件中提供的(幾乎沒有變化,進行一些規範和脫糖)源,因此函數可以專門和甚至可能在呼叫站點內聯。
在哪裏可以使用RULES
。我聽說有人採取特定的規則不開火?我們如何檢查?
您可以使用-ddump-rule-firings
命令行選項來檢查哪些規則已被觸發。這通常會拋出大量已解除規則,因此您必須爲自己的規則搜索一下。
您使用規則
當你有一個功能更有效的版本,特殊工種,如
{-# RULES
"realToFrac/Float->Double" realToFrac = float2Double
#-}
當某些功能可以被更有效的版本替換爲特殊參數時,例如,
{-# RULES
"^2/Int" forall x. x^(2 :: Int) = let u = x in u*u
"^3/Int" forall x. x^(3 :: Int) = let u = x in u*u*u
"^4/Int" forall x. x^(4 :: Int) = let u = x in u*u*u*u
"^5/Int" forall x. x^(5 :: Int) = let u = x in u*u*u*u*u
"^2/Integer" forall x. x^(2 :: Integer) = let u = x in u*u
"^3/Integer" forall x. x^(3 :: Integer) = let u = x in u*u*u
"^4/Integer" forall x. x^(4 :: Integer) = let u = x in u*u*u*u
"^5/Integer" forall x. x^(5 :: Integer) = let u = x in u*u*u*u*u
#-}
- 重寫根據一般規律可能會產生的代碼是更好地優化,例如表達式時
{-# RULES
"map/map" forall f g. (map f) . (map g) = map (f . g)
#-}
在後者的樣式
廣泛使用的RULES
在融合框架製成,例如在text
庫,並且該列表的功能在base
中,不同種類的融合(foldr/build
融合)的實施使用規則。
什麼時候使函數的參數嚴格,什麼時候可以提供幫助?我明白,嚴格論證會使參數被評估爲正常形式,那麼爲什麼我不應該對所有函數參數加嚴格?我如何決定?
製作一個參數嚴格將確保其被評估到弱頭部正常形態,不正常的形式。
你不要讓所有的參數嚴格,因爲有些功能必須是非嚴格一些他們的論據在所有的工作,有些是如果不太嚴格高效的所有參數。
對於examplepartition
必須是非嚴格在其第二個參數上無限列表在所有的工作,更一般在foldr
使用必須是非嚴格的第二個參數中的每個函數,在無限列表工作。上有限列表,具有該功能的非嚴格的第二個參數可以使它顯着更有效(foldr (&&) True (False:replicate (10^9) True)
)。
你讓爭吵嚴格,如果你知道,在任何有價值的工作可以做反正參數必須進行評估。在許多情況下,GHC的嚴格性分析器可以自行完成,但當然不是。
一個非常典型的情況是在循環中或尾部遞歸,其中添加嚴格防止在途中巨大的thunk建設蓄電池。
我不知道哪裏有嚴格的規定,對我來說這是一個經驗問題,過了一段時間,你會學到在哪些地方增加嚴格度可能會有幫助以及傷害的地方。
作爲一個經驗法則,這是有道理的,以保持較小的數據(如Int
)評價,但也有例外。
如何查看並檢查我的程序中是否有空間泄漏?什麼是構成空間泄漏的一般模式?
第一步是使用+RTS -s
選項(如果程序與啓用了rtsopts的鏈接)。這表明你整體使用了多少內存,並且你可以經常判斷你是否有泄漏。 (另外,該程序需要與啓用rtsopts被鏈接) 更翔實的輸出可從與+RTS -hT
選項,產生一個堆輪廓,可以幫助定位的空間泄漏運行的程序來獲得。
如果需要進一步的分析,該程序需要啓用分析編譯(-rtsops -prof -fprof-auto
,中老年GHCs的-fprof-auto
選項不可用,則-prof-auto-all
選項有最接近的對應)。
然後你運行它與各種分析選項,並查看生成的堆配置文件。
空間泄漏的兩個最常見的原因是
第三位可能是採取不必要的共享,GHC做一點公共子表達式消除,但偶爾會在不需要的地方共享長列表。
爲了找到泄漏的原因,我再次知道沒有硬性規定,有時可以通過在一個地方添加嚴格性或在另一個地方添加懶惰來修復泄漏。
我該如何看看是否有太多懶惰的問題?我總是可以檢查堆分析,但我想知道什麼是懶惰傷害的一般原因,示例和模式?
一般來說,懶惰而被通緝,其中結果可以逐步建立起來的,和不想要在沒有結果的一部分可以前處理完成,像留下摺痕或一般尾遞歸函數傳遞。
RHW CH 25? http://book.realworldhaskell.org/read/profiling-and-optimization.html –
@DonStewart謝謝..我已經看過RWH ..問題是我不知道他們做什麼,但我並沒有對當直覺以及他們的使用是重要的而不重要的地方。我問了這個問題找出其他來源,以進一步加深我的理解。 – Satvik