Let's say I have an Data.Array.IO.IOArray i e
(from the array
package) and I would like to read elements from it, processing each element, one by one, in IO, according to some index ordering:
arr :: IOArray I E
ordering :: [I]
processElement :: I -> E -> IO ()
(as we can see, everything is monomorphic).
There are two obvious ways of doing this:
freeze
ing the array first into an immutable array, and using the!
operator:do arr' <- freeze arr forM_ ordering $ \i -> processElement i (arr' ! i)
readArray
'ing each element from the original, mutable array:forM_ ordering $ \i -> do e <- readArray arr i processElement i e
The indices in ordering
are "dense" in the sense that most indices of arr
appear in ordering
.
Which one is more efficient? Also, does the answer depend on these factors:
- Whether the index
ordering
has duplicate indices? - Whether the index
ordering
is monotonically increasing? - Whether the index
ordering
is completely random vs. has large continuous stretches?