
On Mon, Aug 20, 2007 at 11:47:06PM -0700, Ryan Ingram wrote:
Your code is broken in a most evil and insidious way.
Interesting. This is for a toy project, so I'm not too worried, but lets say I wanted to do this "correctly" and I was set on using IOUArray for some reason.
Heh, I'm a lot less worried now. (Somehow I thought this was going into a high-visibility library!)
(The Haskell wiki claims that StorableArray is slower; is that actually the case?)
Good question! I wrote a basic CA benchmark and a much simpler array benchmark, both parameterized by the array type, and couldn't get consistent results, so I'll take this as a "no". stefan@stefans:/tmp$ cat ArrayTest.hs {-# OPTIONS_GHC -fglasgow-exts -cpp #-} import Data.Array.MArray import Data.Bits import Data.Array.IO import Data.Array.Base import Data.Array.Storable import GHC.Exts -- #define ARRAY IOUArray -- uch! iter :: Int -> ARRAY Int Word -> IO () iter 4096 arr = arr `seq` return () iter ix arr = do unsafeWrite arr ix . succ =<< unsafeRead arr ix iter (ix+1) arr bench 100000 arr = arr `seq` return () bench ct arr = do iter 0 arr bench (ct+1) arr main = do arr <- newListArray (0,4095) [1..] bench 0 arr print =<< getElems arr stefan@stefans:/tmp$ ghc -fforce-recomp -DARRAY=IOUArray -O2 ArrayTest.hs && time ./a.out > /dev/null real 0m2.006s user 0m2.028s sys 0m0.008s stefan@stefans:/tmp$ ghc -fforce-recomp -DARRAY=StorableArray -O2 ArrayTest.hs && time ./a.out > /dev/null real 0m1.845s user 0m1.872s sys 0m0.004s stefan@stefans:/tmp$
Which of the following fixes would work now? Which has the lowest probability of not working in the future?
1) Declare f to take Addr# and don't construct a Ptr Word32 I suspect this would be enough unless the GC changed to some sort of continous GC which can happen even without an allocation
Would work now, I think.
2) Declare f to take MutableByteArray# Is this good enough to make the collector happy?
Maybe. In theory the collector should know that an argument passed to a foreign function as a pointer type, should be followed. I'd tentatively call it a bug if this breaks, but it's fragile enough that you should expect to find yourself reporting said bug.
3) Something else I haven't thought of?
If there was no other option, and StorableArray wasn't slower, and I was working on a real project, I'd probably wrap my own around ForeignPtr like Data.ByteString.
Stefan