[Haskell-cafe] Profiling nested case

Mitar mmitar at gmail.com
Sat Jul 12 14:57:09 EDT 2008


(I will reply propely later, I have a project to finish and GHC is
playing me around and does not want to cooperate.)

This project of mine is getting really interesting. Is like playing
table tennis with GHC. Some time it gives a nice ball, sometimes I
have to run around after it. But I just wanted to make a simple
raycasting engine. Not debug GHC. But it is interesting - just I do
not have time just know for playing the change code - compile - run on
known input - check if time elapsed increased (I have to do this even
when I am thinking that I am optimizing things or even when I am
thinking that I am just refactoring code - moving constants to
definitions...). And this is a slow process because every iteration
runs for a few minutes.

The next beautiful example in this series is this function for
computing 4D Julia set fractal:

julia4DFractal :: BasicReal -> World
julia4DFractal param (x,y,z) = julia4D (Q (x / scale) (y / scale) (z /
scale) param) iterations
  where c          = (Q (-0.08) 0.0 (-0.8) (-0.03))
        alphaBlue  = VoxelColor 0 0 (2 / scale) (2 / scale)
        scale      = fromIntegral sceneHeight / 1.8
        threshold  = 16
        iterations = 100 :: Int
        julia4D _ 0                                    = (# alphaBlue,
1 #) -- point is (probably) not in the set
        julia4D q it | qMagnitudeSquared q > threshold = (# noColor, 1
#)   -- point is in the set
                     | otherwise                       = julia4D
(qSquared q + c) (it - 1)
          where distance      = scale * (qMagnitude qN) / (2 *
(qMagnitude qN')) * log (qMagnitude qN)
                (# qN, qN' #) = disIter q (Q 1 0 0 0) iterations
                  where disIter qn qn' 0
     = (# qn, qn' #)
                        disIter qn qn' i | qMagnitudeSquared qn >
threshold = (# qn, qn' #)
                                         | otherwise
     = disIter (qSquared qn + c) (2 * qn * qn') (i - 1)

Please observe that distance is never used. And this is also what GHC
warns. But the trick is that with having this part of a code in there,
the program virtually never finishes (I killed it after 15 minutes).
If I remove everything on and after the "where distance" line it
finishes in 30 seconds. OK, the problem is with (# qN, qN' #), if this
is changed to normal (qN, qN'), then it works. But to notice this ...
This is something you have to spend a day for.


More information about the Haskell-Cafe mailing list