vector
在处理 a ifunsafeUpdate_
函数用于更新 a 的某些元素时,是否可以保持流融合vector
?在我做的测试中,答案似乎是否定的。对于下面的代码,在upd
函数中生成了临时向量,正如核心中所确认的:
module Main where
import Data.Vector.Unboxed as U
upd :: Vector Int -> Vector Int
upd v = U.unsafeUpdate_ v (U.fromList [0]) (U.fromList [2])
sum :: Vector Int -> Int
sum = U.sum . upd
main = print $ Main.sum $ U.fromList [1..3]
在核心中,$wupd
函数用于sum
- 如下所示,它生成新的bytearray
:
$wupd :: Vector Int -> Vector Int
$wupd =
\ (w :: Vector Int) ->
case w `cast` ... of _ { Vector ipv ipv1 ipv2 ->
case main11 `cast` ... of _ { Vector ipv3 ipv4 ipv5 ->
case main7 `cast` ... of _ { Vector ipv6 ipv7 ipv8 ->
runSTRep
(\ (@ s) (s :: State# s) ->
case >=# ipv1 0 of _ {
False -> case main6 ipv1 of wild { };
True ->
case newByteArray# (*# ipv1 8) (s `cast` ...)
of _ { (# ipv9, ipv10 #) ->
case (copyByteArray# ipv2 (*# ipv 8) ipv10 0 (*# ipv1 8) ipv9)
`cast` ...
在 for function 的核心中有一个很好的、紧密的循环,sum
但就在那个循环之前,有一个$wupd
function 调用,因此是一个临时生成。
在此处的示例中,有没有办法避免临时生成?我的想法是,更新索引 i 中的向量是解析流但仅作用于索引 i 中的流(跳过其余部分),并将那里的元素替换为另一个元素的情况。所以,在任意位置更新向量不应该破坏流融合,对吧?