E 'possibile mantenere la fusione flusso durante l'elaborazione di un vector
se unsafeUpdate_
funzione viene utilizzata per aggiornare alcuni elementi di una vector
? La risposta sembra non essere nel test che ho fatto. Per il codice qui sotto, vettore temporaneo viene generata in upd
funzione, come confermato nel nucleo:Nessun flusso di fusione con unsafeUpdate_ in unboxed vettore
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]
Nel nucleo, $wupd
funzione viene utilizzata sum
- come visto sotto, genera nuovo 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` ...
C'è un bel loop stretto nel core per la funzione sum
ma poco prima di quel ciclo, c'è una chiamata alla funzione $wupd
, e quindi una generazione temporanea.
C'è un modo per evitare la generazione temporanea nell'esempio qui? Il modo in cui ci penso, aggiornando un vettore nell'indice i è il caso di analizzare un flusso ma agendo solo sullo stream nell'indice i (saltando il resto) e sostituendo l'elemento con un altro elemento. Quindi, aggiornare un vettore in una posizione arbitraria non dovrebbe interrompere la fusione del flusso, giusto?
parte: 'yarr' supporta fusion e srotolando insieme sul posto che cambia: http: //hackage.haskell .org/packages/archive/yarr/1.3.1/doc/html/Data-Yarr-Repr-Foreign.html # t: F – leventov
@leventov, molto bello! Dal momento che sembra che tu sia l'autore di quella libreria, saresti in grado di condividere come scrivere la funzione di aggiornamento fusibile sul posto per l'esempio vettoriale sopra? Sicuramente, quello che hai fatto per yarr dovrebbe essere applicabile qui, no? – Sal
grande, grande svantaggio di 'yarr-1. *' È strettamente connesso con IO. La modifica sul posto è semplicemente 'do {... write arr 0 2; ...} '. – leventov