
So, I was looking at the implementation of ForeignPtr's in an attempt to determine why they were slow, and have an idea to speed them up.. right now we have: ForeignPtr a = ForeignPtr ForeignObj# !(IORef [IO ()]) | MallocPtr (MutableByteArray# RealWorld) !(IORef [IO ()]) and I think the inderection caused by the disjunction is what is messing things up, not allowing ForeignPtrs to be inlined even in strict contexts as the discriminator must still be examined. so how bout something like data ForeignPtr a = ForeignPtr Addr# !FP -- note FP should be strict but BOXED [2] data FP = ForeignPtrObj ForeignObj# {-# UNPACK #-} !(IORef [IO ()]) | MallocPtr (MutableByteArray# RealWorld) {-# UNPACK #-} !(IORef [IO ()]) by caching the frequently used Addr in a place where it may be unboxed and hiding the details only needed when finalizing or garbage collecting, I think we can bring ForeignPtrs up to the speed (if not space) performance of plain old Ptr's. John [2] FP should be strict yet boxed so ForeignPtrs may be unboxed in various places without duplicating the rarely used bookkeeping info. hopefully touchForeignPtr (ForeignPtr _ fp) = IO $ \s -> case touch# fp s of s -> (# s, () #) is good enough to keep things alive. this is also why it is safe to UNPACK the IORefs in FP -- John Meacham - ⑆repetae.net⑆john⑈