Performance bug maybe

Scott Dillard sedillard at
Mon Dec 17 15:54:47 EST 2007


I think I found a performance bug. Either that, or something is going
on that I don't understand.

I've attached an example program. Here's my session with it:

ghc --make -O2 MaybeBug.hs; time ./MaybeBug +RTS -tstderr

[1 of 1] Compiling Main             ( MaybeBug.hs, MaybeBug.o )
Linking MaybeBug ...
./MaybeBug +RTS -tstderr
<<ghc: 800037360 bytes, 4 GCs, 40960/40960 avg/max bytes residency (1
samples), 383M in use, 0.00 INIT (0.00 elapsed), 3.96 MUT (4.36
elapsed), 0.00 GC (0.00 elapsed) :ghc>>

real	0m4.408s
user	0m3.960s
sys	0m0.448s

ghc --make -O2 MaybeBug.hs -DSLOW -no-recomp; time ./MaybeBug +RTS -tstderr
[1 of 1] Compiling Main             ( MaybeBug.hs, MaybeBug.o )
Linking MaybeBug ...
./MaybeBug +RTS -tstderr
<<ghc: 4000037408 bytes, 6106 GCs, 400588800/400588800 avg/max bytes
residency (2 samples), 765M in use, 0.00 INIT (0.00 elapsed), 9.71 MUT
(10.53 elapsed), 0.05 GC (0.08 elapsed) :ghc>>

real	0m10.717s
user	0m9.761s
sys	0m0.876s

There are two functions, initArray1 and initArray2, that have exactly
the same implementation. I use them to initialize two arrays. If I use
initArray1 on the first, and initArray2 on the second, then things get
inlined and specialized wonderfully and no heap is used. If I use
initArray1 to initialize both arrays, then less inlining happens.
Since I'm doing possibly dangerous things with unsafePerformIO, I'm
inclined to think this is not a bug, but I'm still wondering what's
going on.

On that note: is this use of unsafePerformIO in fact dangerous? I'm
aware that allocating memory inside unsafePerformIO is not wise,
especially when that function is to be inlined. If the function body
is duplicated at the call site, I might get two identical arrays where
I could have one that is shared. I can live with that possibility, but
I'm more worried about the allocation being floated out of the
unsafePerformIO, and having unintended sharing. Can this happen, the
way I've written it? The inlining seems to be crucial for performance,
so that constructor specialization can kick in.

If there's a better way to do truly polymorphic unboxed immutable
arrays, I'm all ears. (I'm aware of Bulat's ArrayRef library, but it
doesn't seem to be maintained.. is it?)

-------------- next part --------------
A non-text attachment was scrubbed...
Name: MaybeBug.hs
Type: text/x-haskell
Size: 1157 bytes
Desc: not available
Url :

More information about the Glasgow-haskell-users mailing list