[Haskell-cafe] Code runs 7x FASTER with profiling

Neil Mayhew 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 
statically-optimized approach.)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20171207/7bb7527c/attachment.html>

More information about the Haskell-Cafe mailing list