理解两个尾递归映射函数的性能差异

时间:2015-08-15 05:11:39

标签: recursion ocaml tail-recursion map-function

来自 Jason Hickey的Objective Caml简介,我们有一个尾递归映射函数:

let rec rev_accum result = function  
    h::tl -> rev_accum (h :: result) tl
    | [] -> result

let rec rec_map f result = function
    h :: tl -> rec_map  f (f h :: result)   tl 
    | [] -> result 

let map1 f l = rev_accum  [] ( rec_map f [] l )

它将遍历列表两次。考虑这个替代方案:

let rec rec_map2 f result = function
    h :: tl -> rec_map2  f ( result @[f h]) tl 
    | [] -> result 

let map2 f l = rec_map2 f [] l ; 

第二个会比第一个快吗?

1 个答案:

答案 0 :(得分:3)

重复添加到列表的末尾需要在列表的最终长度中为二次方的时间。另一种说法是它遍历列表 n 次,这很容易超过两次。因此,第二个实现通常会慢得多。第一个实现是线性的,即使它遍历列表两次。

(当然你不知道函数f的性能。)