I wrote a function in Haskell which looks like this:
maxSumme :: [[Int]] -> Int
maxSumme [] = 0
maxSumme (x:l) = if subSumme x < maxSumme l then maxSumme l else subSumme x
subSumme :: [Int] -> Int
subSumme [] = 0
subSumme (x:l) = x + subSumme(l)
-- function call
maxSumme [[7,2,4],[5,8,1],[7,9,2]] -- with 25 innerLists
I tested it but this method is very slowly. If I call it with a list of 25 innerLists with 3 items it takes up to a minute to calculate the maxSumme. That is not normal isn't it? I must have made a mistake but I can't find it. How can I optimize my method? Is there a faster way to do this?
EDIT: I think found the mistake. I'm convinced that it is the maxSumme l then maxSumme l
. I loop throught the list to often each time and that takes so long. But actually I have no idea how to avoid that.
let
lifting themaxSumme l
reduces the time complexity from exponential to linear. CSE is not always ok in lazy languages, but it is in this case. – Philip JFsubSumme x
inlet ssx = subSumme x in ...
(and replacingsubSumme x
withssx
). It's like defining a new variable, in some sort. Also the same goes formaxSumme l
. CSE means "common subexpression elimination". If the compiler would have realized that those expressions are the same, it could have done what we just described and opmitized the hell out of the code, but for some reason it didn't (maybe it's not always ok as Philip suggests). – GuidosubSumme
, but the unsharedmaxSumme
. LeavingsubSumme
unshared costs double; leavingmaxSumme
unshared doubles the number of recursive calls, which leads to an exponential cost in the length of the list being recursed on. – Daniel Wagner