Performance 作为左折叠实现的列表连接的性能

Performance 作为左折叠实现的列表连接的性能,performance,list,haskell,time-complexity,lazy-evaluation,Performance,List,Haskell,Time Complexity,Lazy Evaluation,考虑实现为左折叠的列表连接,即,foldl(++)[]。 在一种惰性评估语言(如Haskell)中,此实现的复杂性是什么? 我知道在严格的语言中,性能是元素总数的二次方,但是当涉及懒惰时会发生什么呢 我试图手工计算表达式([1,2,3]++[4,5,6])++[7,8,9](对应于foldl(+)[[1,2,3],[4,5,6],[7,8,9]) 似乎每个元素只遍历一次,但我不确定我的推理是否正确: ([1,2,3] ++ [4,5,6]) ++ [7,8,9] = { rewrite expr

考虑实现为左折叠的列表连接,即,
foldl(++)[]
。 在一种惰性评估语言(如Haskell)中,此实现的复杂性是什么? 我知道在严格的语言中,性能是元素总数的二次方,但是当涉及懒惰时会发生什么呢

我试图手工计算表达式
([1,2,3]++[4,5,6])++[7,8,9]
(对应于
foldl(+)[[1,2,3],[4,5,6],[7,8,9]
) 似乎每个元素只遍历一次,但我不确定我的推理是否正确:

([1,2,3] ++ [4,5,6]) ++ [7,8,9]
= { rewrite expression in prefix notation }
(++) ((++) [1,2,3] [4,5,6]) [7,8,9]
= { the first (++) operation needs to pattern match on its first argument; so it evaluates the first argument, which pattern matches on [1,2,3] }
(++) (case [1,2,3] of {[] -> [4,5,6]; x:xs' -> x:(++) xs' [4,5,6]}) [7,8,9]
= { x = 1, xs' = [2,3] }
(++) (1:(++) [2,3] [4,5,6]) [7,8,9]
= { the first (++) operation can now pattern match on its first argument }
1:([2,3] ++ [4,5,6]) ++ [7,8,9]
我假设
(++)
的以下实现:

假设我们有
([1,2,3]++[4,5,6])++[7,8,9]

([1,2,3]++[4,5,6])++[7,8,9]
(1:([2,3]++[4,5,6))++[7,8,9]
1:(([2,3]++[4,5,6])++[7,8,9])
1:((2:([3]++[4,5,6])++[7,8,9])
1:2:(([3]++[4,5,6])++[7,8,9])
1:2:(3:([]++[4,5,6])++[7,8,9])
1:2:3:(([]++[4,5,6])++[7,8,9])
1:2:3:([4,5,6]++[7,8,9])
1:2:3:4:([5,6] ++ [7,8,9])
1:2:3:4:5:([6] ++ [7,8,9])
1:2:3:4:5:6:([] ++ [7,8,9])
1:2:3:4:5:6:[7,8,9]
[1,2,3,4,5,6,7,8,9]
注意第一个列表中的每个元素必须移动两次吗?那是因为距离终点还有两分钟。通常,如果我们有
((a1++a2++a3)+…an)
列表中的每个元素
ai
都必须移动
n-i

所以,如果你想要整个列表,它是二次的。如果您想要第一个元素,并且您有
n
列表,那么它是
n-1
*操作(我们需要执行
++
n
次的步骤)。如果您想要
i
th元素,它是之前所有元素的操作数,加上
k-1
,它位于
k
th列表中,从末尾开始计数


*加上
foldl
本身的
n
操作,如果我们想学究气

也许你的问题得到了明确的回答,
foldl
由于懒惰而对性能有影响。另外,与之相比:如果你不坚持先形成列表,然后再扫描列表,您只需支付连接价格一次。谢谢!这是正确的。同时,我发现,他的前半部分也回答了我的问题。
([1,2,3]++[4,5,6])++[7,8,9]
(1:([2,3]++[4,5,6))++[7,8,9]
1:(([2,3]++[4,5,6])++[7,8,9])
1:((2:([3]++[4,5,6])++[7,8,9])
1:2:(([3]++[4,5,6])++[7,8,9])
1:2:(3:([]++[4,5,6])++[7,8,9])
1:2:3:(([]++[4,5,6])++[7,8,9])
1:2:3:([4,5,6]++[7,8,9])
1:2:3:4:([5,6] ++ [7,8,9])
1:2:3:4:5:([6] ++ [7,8,9])
1:2:3:4:5:6:([] ++ [7,8,9])
1:2:3:4:5:6:[7,8,9]
[1,2,3,4,5,6,7,8,9]