From e5e495a1815a7d9c519c728c6c1084fcd045374b Mon Sep 17 00:00:00 2001 From: Nicolas DI PRIMA Date: Wed, 31 Aug 2016 19:01:59 +0100 Subject: [PATCH] UArray.concat: fill the array from the end --- Foundation/Array/Unboxed.hs | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/Foundation/Array/Unboxed.hs b/Foundation/Array/Unboxed.hs index 5e62da3f..9ecea58a 100644 --- a/Foundation/Array/Unboxed.hs +++ b/Foundation/Array/Unboxed.hs @@ -439,27 +439,16 @@ append a b concat :: PrimType ty => [UArray ty] -> UArray ty concat [] = empty -concat l = - case filterAndSum (Size 0) [] l of - (_,[]) -> empty - (_,[x]) -> x - (totalLen,chunks) -> runST $ do - r <- new totalLen - doCopy r (Offset 0) chunks - unsafeFreeze r - where - -- TODO would go faster not to reverse but pack from the end instead - filterAndSum !totalLen acc [] = (totalLen, Prelude.reverse acc) - filterAndSum !totalLen acc (x:xs) - | len == Size 0 = filterAndSum totalLen acc xs - | otherwise = filterAndSum (len+totalLen) (x:acc) xs - where len = lengthSize x - - doCopy _ _ [] = return () - doCopy r i (x:xs) = do - unsafeCopyAtRO r i x (Offset 0) lx - doCopy r (i `offsetPlusE` lx) xs - where lx = lengthSize x +concat l = runST $ fromEnd (Size 0) l >>= unsafeFreeze + where + fromEnd !sz [] = new sz + fromEnd !sz (x:xs) + | null x = fromEnd sz xs + | otherwise = do + let len = lengthSize x + mua <- fromEnd (sz + len) xs + unsafeCopyAtRO mua (sizeAsOffset sz) x (Offset 0) len + return mua -- | update an array by creating a new array with the updates. --