ForeignPtr performance

Scott Dillard sedillard at ucdavis.edu
Sun Dec 16 15:57:33 EST 2007


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


More information about the Glasgow-haskell-users mailing list