即使不再使用旧的矢量,是否创建了新的矢量? [英] Are new vectors created even if the old ones aren't used anymore?

查看:97
本文介绍了即使不再使用旧的矢量,是否创建了新的矢量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



鉴于我永远不会使用细胞更新后某个细胞的旧值。更新操作是否总是创建一个新的向量,反映更新,还是将它作为就地更新?



注意:我知道 Data.Vector.Mutable

解决方案

不,数据。矢量是使用流融合构建的, 。这意味着,如果您正在执行的构建操作的顺序可以融合掉,那么Vector就不会被构建,您的代码将变为优化循环。

Fusion通过将构建向量的代码转换为代码来完成工作,这些代码构建并断开流,然后将流放入编译器可以执行的窗体中优化。



所以代码看起来像

  foo :: Int 
foo = sum as
其中as,bs,cs,ds,es :: Vector Int
as = map(* 100)bs
bs = take 10 cs
cs = zipWith(+)(生成1000 id)ds
ds = cons 1 $ cons 3 $ map(+2)es
es = replicate 24000 0

尽管看起来建立并拆除了一些非常大的向量,但它们可以一直融合到内部循环,只计算并添加10个数字s。

你提出的建议很棘手,因为它要求你知道在其他地方不存在任何对术语的引用,这会对任何复制参考一个环境。而且,它与懒惰的相互作用很差。你需要附加一点仿射增补到你显然没有评估过的thunk上。但是,在多线程环境下这样做很容易出错,很难找到正确的答案。


This question is about the Data.Vector package.

Given the fact that I'll never use the old value of a certain cell once the cell is updated. Will the update operation always create a new vector, reflecting the update, or will it be done as an in-place update ?

Note: I know about Data.Vector.Mutable

解决方案

No, but something even better can happen.

Data.Vector is built using "stream fusion". This means that if the sequence of operations that you are performing to build up and then tear down the vector can be fused away, then the Vector itself will never even be constructed and your code will turn into an optimized loop.

Fusion works by turning code that would build vectors into code that builds up and tears down streams and then puts the streams into a form that the compiler can see to perform optimizations.

So code that looks like

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

despite appearing to build up and tear down quite a few very large vectors can fuse all the way down to an inner loop that only calculates and adds 10 numbers.

Doing what you proposed is tricky, because it requires that you know that no references to a term exist anywhere else, which imposes a cost on any attempt to copy a reference into an environment. Moreover, it interacts rather poorly with laziness. You need to attach little affine addenda to the thunk you conspicuously didn't evaluate yet. But to do this in a multithreaded environment is scarily race prone and hard to get right.

这篇关于即使不再使用旧的矢量,是否创建了新的矢量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆