gpt4 book ai didi

haskell - 如何让 foldl 消耗恒定内存?

转载 作者:行者123 更新时间:2023-12-02 02:46:17 26 4
gpt4 key购买 nike

我们定义了以下数据类型 Stupid :

import qualified Data.Vector as V
import Data.List (foldl')
data Stupid = Stupid {content::V.Vector Int, ul::Int} deriving Show

现在我有两个稍微不同的代码。
foldl' (\acc x->Stupid{content=(content acc) V.// [(x,x+123)],ul=1}) (Stupid {content=V.replicate 10000 10,ul=1}) $ take 100000 $ cycle [0..9999]

占用恒定内存(~100M),而
foldl' (\acc x->Stupid{content=(content acc) V.// [(x,x+123)],ul=ul acc}) (Stupid {content=V.replicate 10000 10,ul=1}) $ take 100000 $ cycle [0..9999]

占用大量内存(~8G)。

理论上,只有一份当前 Stupid尽管在这两种情况下的过程中都需要对象。如果我想访问和记录 ul acc,我不明白为什么内存消耗会有如此大的差异。 .

如果我需要访问 ul acc,有人可以解释为什么会发生这种情况并提供恒定内存的解决方法吗? ?谢谢。

注意:我知道我可以批量替换向量,此脚本仅用于演示目的,因此请不要修改该部分。

最佳答案

我会尝试强制 Stupid 的字段看看是否有帮助。

let f acc x = c `seq` a `seq` Stupid{content=c,ul=a}
where
c = content acc V.// [(x,x+123)]
a = ul acc
in foldl' f (Stupid {content=V.replicate 10000 10,ul=1}) $
take 100000 $
cycle [0..9999]

这应该几乎等同于强制函数的参数:
foldl' (\acc x -> acc `seq` x `seq` 
Stupid{content=(content acc) V.// [(x,x+123)],ul=ul acc})
(Stupid {content=V.replicate 10000 10,ul=1}) $ take 100000 $ cycle [0..9999]

(这也可以用 bang 模式写,如果你喜欢那些。)

另一种更激进的选择是在 Stupid 的定义中使用严格注释。构造函数。
data ... = Stupid { content = ! someType , ul :: ! someOtherType }

这将始终强制在整个程序中使用这些字段。

关于haskell - 如何让 foldl 消耗恒定内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54784679/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com