[Haskell-beginners] profiling weirdness?
daniel.is.fischer at web.de
Tue Jun 8 20:41:29 EDT 2010
On Wednesday 09 June 2010 01:23:56, Thomas wrote:
> Hello all!
> Currently this is more of a curiosity for me rather than a real obstacle
> to learn Haskell, but I'd appreciate any insight into this behaviour
> Given the (dumb, I know, but it's for illustration purpose) program:
> import Data.Char
> type Position = (Char, Integer)
> sameSquare :: Position -> Position -> Bool
> sameSquare p1 p2
> = ssqHelper p1 p2
> ssqHelper :: Position -> Position -> Bool
> ssqHelper (r1, c1) (r2, c2)
> | (((c1-1) `div` 3) == ((c2-1) `div` 3) && ((((ord r1) - 65)
> `div` 3) == (((ord r2) - 65) `div` 3))) = True
> | otherwise = False
> main :: IO ()
> main = print (sameSquare ('A', 2) ('B', 2))
> If I compile this with profiling info and run the profiler all seems
> well (independently of optimization settings). Now, if I comment the
> line --ssqHelper :: Position -> Position -> Bool
> and do the same (compile with profiling info) I can see rather
> surprising results. While I'd expect exactly one call to ssqHelper for
> every call to sameSquare this is actually only the case if compiled
> without optimizations. Using -O2 when compiling I get a full 5 calls of
> ssqHelper for every call to sameSquare.
No, you don't, fortunately. It's an artifact of the code generation. When
you compile with optimisations, GHC generates a specialised version of
ssqHelper and it inserts several SCC pragmas in that (as well as in the
polymorphic version if ssqHelper is exported), while without optimisations
it only generates a specialised wrapper and inserts only one SCC pragma in
the polymorphic worker.
When the code comes across an SCC pragma, that counts as one entry (NB,
entries /= calls).
So the unoptimised code meets only one pragma per call, hence one entry.
The optimised code meets several pragmas (the number depends on the code-
path taken) and records several entries per call.
> I am unable to imagine an optimization that would be more efficient with
> five calls instead of one. And I do not understand either what this has
> to do with the type annotation. Within such a trivial program the
> inferred type should be equivalent, shouldn't it?
Not quite. No optimisations means GHC generates polymorphic code without
the type signature. Only with optimisations does it care that ssqHelper is
not exported (I assume you didn't give a module declaration, so it's taken
to be "module Main (main) where") and used only at the one type, so
produces only the specialised version [or two versions if ssqHelper is
> Actually ghci generalizes slightly: Integral instead of Integer. But
> that's no clue for me either...
> BTW I'm using ghc 6.10.4. (In case it matters.)
Not much. With 6.12, you get only 3 entries to ssqHelper per sameSquare
> Any hint would be appreciated.
More information about the Beginners