是否创建了新的向量,即使旧的向量不再使用了?

has*_*ine 7 haskell vector mutable

这个问题是关于Data.Vector包裹的.

鉴于一旦更新单元格,我将永远不会使用某个单元格的旧值.更新操作是否总是创建一个新的向量,反映更新,还是作为就地更新完成?

注意:我知道 Data.Vector.Mutable

Edw*_*ETT 13

不,但更好的事情可能会发生.

Data.Vector使用"流融合"构建.这意味着如果您正在执行的操作序列构建然后拆除向量可以被融合掉,那么Vector本身将永远不会被构造,并且您的代码将变成优化的循环.

融合的工作方式是将构建向量的代码转换为构建和拆除流的代码,然后将流放入编译器可以看到执行优化的表单中.

所以代码看起来像

foo :: Int
foo = sum as
   where as, bs, cs, ds, es :: Vector Int
         as = map (*100) bs 
         bs = take 10 cs
         cs = zipWith (+) (generate 1000 id) ds
         ds = cons 1 $ cons 3 $ map (+2) es 
         es = replicate 24000 0
Run Code Online (Sandbox Code Playgroud)

尽管看起来建立和拆除了相当多的非常大的向量可以一直融合到一个只计算和增加10个数字的内循环.

执行您提出的建议很棘手,因为它要求您知道在其他任何地方都不存在对术语的引用,这会导致将任何将引用复制到环境中的成本.而且,它与懒惰的相互作用相当差.你需要在你明显没有评估的thunk上添加一些仿射附加物.但是,要在多线程环境中执行此操作,可能会出现竞争,并且很难做到正确.

  • @brence:如果你的算法有一个合适的结构,懒惰当然可以让你获得恒定的空间,但是当结构被强制时你仍然会在thunk之间跳跃.融合优化是关于切断间接并将它们全部结合在一起.我的印象是,与幼稚的懒惰形式相比,融合版本仅通过显着的常数因素"改善",而不是整体资源复杂性的改善. (2认同)