Skip to content

Commit 4c8bcd3

Browse files
committed
Improve performance of 'toUnfoldable'
Just use an integer index for the unfolding, as opposed to the uncons' implementation, which was constructing all of the tails of the input array.
1 parent e139d4e commit 4c8bcd3

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/Data/Array.purs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,12 @@ import Partial.Unsafe (unsafePartial)
128128

129129
-- | Convert an `Array` into an `Unfoldable` structure.
130130
toUnfoldable :: forall f a. Unfoldable f => Array a -> f a
131-
toUnfoldable = unfoldr $ uncons' (const Nothing) (\h t -> Just (Tuple h t))
131+
toUnfoldable xs = unfoldr f 0
132+
where
133+
len = length xs
134+
f i
135+
| i < len = Just (Tuple (unsafePartial (unsafeIndex xs i)) (i+1))
136+
| otherwise = Nothing
132137

133138
-- | Convert a `Foldable` structure into an `Array`.
134139
fromFoldable :: forall f a. Foldable f => f a -> Array a

test/Test/Data/Array.purs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import Prelude
55
import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (log, CONSOLE)
77

8-
import Data.Array (range, replicate, foldM, unzip, zip, zipWithA, zipWith, intersectBy, intersect, (\\), deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group', group, span, dropWhile, drop, takeWhile, take, sortBy, sort, catMaybes, mapMaybe, mapWithIndex, filterM, filter, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, (!!), uncons, init, tail, last, head, insertBy, insert, snoc, (:), length, null, singleton, fromFoldable)
9-
import Data.Foldable (for_, foldMapDefaultR, class Foldable, all)
8+
import Data.Array (range, replicate, foldM, unzip, zip, zipWithA, zipWith, intersectBy, intersect, (\\), deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group', group, span, dropWhile, drop, takeWhile, take, sortBy, sort, catMaybes, mapMaybe, mapWithIndex, filterM, filter, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, (!!), uncons, init, tail, last, head, insertBy, insert, snoc, (:), length, null, singleton, fromFoldable, toUnfoldable)
9+
import Data.Foldable (for_, foldMapDefaultR, class Foldable, all, traverse_)
1010
import Data.Maybe (Maybe(..), isNothing, fromJust)
1111
import Data.NonEmpty ((:|))
1212
import Data.NonEmpty as NE
@@ -308,6 +308,17 @@ testArray = do
308308
assert $ length arr == n
309309
assert $ all (_ == elem) arr
310310

311+
log "toUnfoldable"
312+
let toUnfoldableId xs = toUnfoldable xs == xs
313+
traverse_ (assert <<< toUnfoldableId)
314+
[ []
315+
, [1]
316+
, [1,2,3]
317+
, [2,3,1]
318+
, [4,0,0,1,25,36,458,5842,23757]
319+
]
320+
321+
311322
nil :: Array Int
312323
nil = []
313324

0 commit comments

Comments
 (0)