我很好奇如何优化此代码:优化部分计算在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