[Haskell-cafe] Code runs 7x FASTER with profiling
neil_mayhew at users.sourceforge.net
Thu Dec 7 21:25:49 UTC 2017
On 2017-12-07 12:49 AM, Jonas Scholl wrote:
Looking at the produced core of both versions reveals that in the
profiled build a closure of type Regex is floated to top level. The
non-profiled build doesn’t do this, thus it recompiles the regex for
every iteration. This is most likely the source of the slowdown of
the non-profiled build.
Thanks, Jonas. This does indeed seem to be the problem. I changed the
code to use a compiled regex (with |makeRegex| and |match| instead of
|=~|) but in the non-profiling case the run-time doesn’t improve unless
I float the compiled regex myself:
|parseFilename :: String -> Either String (String, String) parseFilename
fn = case (pattern `match` fn :: [[String]]) of [[_, full, _, time]] ->
Right $ (full, time) _ -> Left fn pattern :: Regex pattern = makeRegex
Then it runs 2-3x faster than the profiled code.
The question remains, however: why doesn’t the ghc optimizer spot this
fairly obvious loop-invariant in the non-profiled build when it does
manage to spot it in the profiled one? In other words, when I make
|pattern| a local definition of |parseFilename|, why isn’t it treated as
a CAF that’s evaluated only once (‘floated to the top level’)? Enabling
profiling shouldn’t change the meaning of a program.
I remember back in the day having to be careful with regexes in Python
to make sure they were always precompiled outside of loops and
functions, but one of the nice things about Haskell is that one can
usually let the compiler take care of this. (Nowadays Python gets around
this by caching compiled regexes, but I prefer Haskell’s
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe