I've started diving into Haskell by trying to solve some small problems.
I've stumbled upon a big performance difference(~100-200x) between the "standard haskell-friendly" solution and my "very-ugly and haskell-unfriendly" version.
I'm sure for fellow haskellers this difference in performance has a good reason, which I'm missing, and can educate me on this topic.
The problem: Find the maximum 5 digit number inside a numerical string
Both use the same concept in solving: generate all 5 digit numbers and find the maximum.
Elegant and fast code
digit5 :: String -> Int
digit5 = maximum . map (read . take 5) . init . tails
Ugly and very slow code(once the string size is big)
digit5' :: String -> String -> String
-- xs - input string
-- maxim - current maximal value
digit5' xs maxim
| (length xs) < 5 = maxim
| y > maxim = digit5' (drop 1 xs) y -- use new detected maximum value
| otherwise = digit5' (drop 1 xs) maxim
where y = take 5 xs
digit5 :: String -> Int
digit5 xs
-- return the original string if the input size is smaller than 6
| length (xs) < 6 = read xs
| otherwise = read $ digit5' xs "00000"
For small inputs I get roughly the same execution times, for big inputs I start to see very big differences(for an input of 44550 elements):
Computation time for ugly version: 2.047 sec
Computation time for nice version: 0.062 sec
My superficial understanding of this is that the fast code is using pre-available higher order functions. For the slower version recursion is used but I think tail biting should be possible. But at a naive level, to me both seem to do the same thing.
While the slower function does comparisons on strings instead of converting them to numbers, I've also tried converting the strings to ints but without any big improvement
I've tried compiling using ghc without any flags and with the following commands:
ghc
ghc -O2
ghc -O2 -fexcess-precision -optc-O3 -optc-ffast-math -no-
recomp
stack runhaskell
ghc -O3
For sake of reproducibility I'm adding a link to the code contaning also the test vector: https://pastebin.com/kuS5iKgd