我很好奇如何優化此代碼:優化部分計算在Haskell
fun n = (sum l, f $ f0 l, g $ g0 l)
where l = map h [1..n]
假設f
,f0
,g
,g0
和h
都是昂貴的,但l
的創建和存儲是非常昂貴。
正如所寫,l
被存儲,直到返回的元組被完全評估或垃圾收集。相反,length l
,f0 l
和g0 l
都應該在它們中的任何一個都被執行時執行,但f
和g
應該被延遲。
看來這種行爲可能是固定的寫作:
fun n = a `seq` b `seq` c `seq` (a, f b, g c)
where
l = map h [1..n]
a = sum l
b = inline f0 $ l
c = inline g0 $ l
還是很相似:
fun n = (a,b,c) `deepSeq` (a, f b, g c)
where ...
我們或許可以指定一幫內部類型來達到相同的效果好,看起來很痛苦。還有其他選擇嗎?
另外,我明明跟我inline
s表示編譯器融合sum
,f0
和g0
成一個單一循環,構建和消耗l
逐項希望。我可以通過手動內聯來明確這一點,但這很吸引人。有沒有辦法明確阻止創建和/或強制內聯列表l
?可能在編譯期間內聯或融合失敗時會產生警告或錯誤的編譯指示?
順便說一句,我很好奇,爲什麼seq
,inline
,lazy
,等等,都由let x = x in x
的序幕定義。這僅僅是爲了給他們一個編譯器的重寫定義嗎?
回覆最後一個問題:http://stackoverflow.com/a/8654407/1011995 – 2012-04-22 10:02:49
'f0'和'g0'完全是任意的,還是可以用'foldr'來寫? – dave4420 2012-04-22 10:38:49
這裏有沒有足夠的(a,b,c)-accumulator的簡單摺疊? – Sarah 2012-04-22 12:19:10