haskell - foldl with (++) is a lot slower than foldr -


why foldl slower foldr ? have list of lists "a" like

a = [[1],[2],[3]] 

and want change list using fold

foldr (++) [] 

it works fine (time complexity o(n)). if use foldl instead, slow (time complexity o(n^2)).

foldl (++) [] 

if foldl folding input list left side,

(([] ++ [1]) ++ [2]) ++ [3] 

and foldr right side,

[1] ++ ([2] ++ ([3] ++ [])) 

the number of computations (++) supposed same in both cases. why foldr slow? per time complexity, foldl looks if scanning input list twice many times foldr. used following computer time

length $ fold (++) [] $ map (:[]) [1..n]   (fold either foldl or foldr) 

it's because of how ++ works. note is defined induction on first argument.

[]     ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) 

the number of recursive calls depends on length xs.

because of this, in xs ++ ys more convenient have small xs , large ys other way around.

note folding on right achieves this:

[1] ++ ([2] ++ ([3] ++ ... 

we have short (o(1)-length) lists on left of ++, making fold cost o(n).

instead folding on left bad:

((([] ++ [1]) ++ [2]) ++ [3]) ++ ... 

the left arguments become larger , larger. hence, o(n^2) complexity here.

this argument can made more precise considering how output list demanded. 1 can observe foldr produces result in "streaming" fashion, demanding e.g. first output list cell forces little part of input -- first ++ needs performed, , first recursive step needed! instead demanding first item foldl result force all ++ calls, making quite expensive (even if each call needs 1 recursive step, there o(n) calls).


Comments

Popular posts from this blog

asp.net - How to correctly use QUERY_STRING in ISAPI rewrite? -

jsf - "PropertyNotWritableException: Illegal Syntax for Set Operation" error when setting value in bean -

laravel - Undefined property: Illuminate\Pagination\LengthAwarePaginator::$id (View: F:\project\resources\views\admin\carousels\index.blade.php) -