
Hi, I do a lot of programming with small compound objects, things like 3d vectors or RGBA tuples for images. For performance reasons, I keep them in StorableArrays, since there is no way to use these things with UArrays. (But that's a topic for another thread.) Some how the notion got into my head that StorableArrays were slow, I think from old versions of GHC. So I've gotten into the habit of using withStorableArray and peek/poke to work on my arrays. This, as you can imagine, is cumbersome. Not only because of the extra typing, but also because I have to do everything in the IO monad, even if the array is read-only. So I'm thinking about writing my own IArray instance using ForeignPtr for storage and unsafePerformIO for access. I did a little experiment, comparing
forM_ [0..lots] $ \i -> withForeignPtr fp $ \p -> pokeElemOff p i i
to
withForeignPtr fp $ \p -> forM_ [0..lots] $ \i -> pokeElemOff p i i
And there seemed to be no difference in running time, which is great. So I'm thinking of making unsafeAt something like
unsafeAt (MyArray fp) i = unsafePerformIO $ withForeignPtr fp $ \p -> peekElemOff p i
My question is: what exactly does GHC.Prim.touch# do? This appears to be the critical function of withForeignPtr, and if I write my IArray instance as above, I have no way to float this touch# out of my loops, as I currently do using withStorableArray. It appears from my simple experiment that touch# does nothing at runtime. But maybe this is only because no memory is allocated inside my simple loop? Maybe if I write non-trivial loops, then touch# will actually cost something? Intensely curious, Scott