【发布时间】:2015-05-06 06:40:51
【问题描述】:
Thinking Functionally with Haskell 提供了以下代码,用于计算 Float 列表的 mean。
mean :: [Float] -> Float
mean [] = 0
mean xs = sum xs / fromIntegral (length xs)
教授。理查德伯德:
现在我们准备好看看 mean 的真正问题是什么:它有空间泄漏。计算
mean [1..1000]将导致列表在求和后扩展并保留在内存中,因为有第二个指针指向它,即在计算其长度时。
如果我正确理解了这段文字,他的意思是,如果在长度计算中没有指向 xs 的指针,那么 xs 内存可能已经被释放在计算 @ 987654327@?
我的困惑是 - 如果 xs 已经在内存中,那么 length 函数不是只会使用已经被占用的相同内存吗?
这里的空间泄漏我不明白。
【问题讨论】:
-
嗯,“泄漏”对我来说似乎有点奇怪......但绝对要注意一件事:stackoverflow.com/a/2380437/667648 sum xs 被计算出来,然后长度 xs 被计算出来,通过两次而不是一次.
-
与问题无关,但如果您要编写一个平均函数,请让它返回一个
Maybe。这里无法区分真 0 和假 0。 -
Haskell 公文:计算
sum xs不是问题。计算length xs不是问题。计算sum xs / length xs是个问题。 -
@DanielWagner 我不明白这一点。鉴于
sum是用foldl懒惰地定义的,它不会导致空间泄漏吗?在我的笔记本电脑中提供sum [1..10000000]会增加笔记本电脑的内存使用率。而mysum = foldl' (+) 0在恒定的内存空间上运行? -
@Sibi 这确实是一个不幸的历史细节。但是,在任何地方都用
foldl' (+) 0代替sum确实有损公案的美感,同时对新手几乎没有兴趣,你不同意吗? =)
标签: haskell