Cheap ForeignPtr allocation

Manuel M T Chakravarty chak at cse.unsw.edu.au
Tue Sep 3 04:41:20 EDT 2002


"Simon Marlow" <simonmar at microsoft.com> wrote,

> I'd like to propose two new functions for the ForeignPtr interface:
> 
> 	mallocForeignPtr      :: Storable a => IO (ForeignPtr a)
>       mallocForeignPtrBytes :: Int -> IO (ForeignPtr a)
> 
> (the names can change, of course).  The implementations are trivial in
> terms of existing things:
> 
>     mallocForeignPtr = do
>       p <- malloc
>       newForeignPtr p free
> 
>     mallocForeignPtrBytes size = do
>       p <- mallocBytes size
>       newForeignPtr p free
> 
> However, in GHC we can provide a far more efficient implementation by
> using pinned ByteArray#s, avoiding the overhead of malloc()/free() and
> the finalizer.  Since this is quite a common idiom when using
> ForeignPtrs, I think it's a good case to optimise.
> 
> I did a little test, and using the above functions gave a 6x improvement
> in a small example which just repeatedly allocated a new ForeignPtr and
> passed it to a foreign function.
> 
> The GHC implementation is to extend the ForeignPtr type like this:
> 
>   data ForeignPtr a 
>     = ForeignPtr ForeignObj#
>     | MallocPtr  (MutableByteArray# RealWorld)
> 
> so it does in theory slow down normal ForeignPtrs slightly, but I didn't
> measure any difference in the limited tests I did.

I vaguely remeber that in the context of the withForeignPtr
discussion we where once trying to achieve some similar
effect (but couldn't come up with something that would
work).  Do you remember?  Does this, then, effectively solve
this old problem?  Wouldn't you want newXXX and withXXX
variants of the above, too?

Cheers,
Manuel



More information about the FFI mailing list