【发布时间】:2020-09-07 04:25:41
【问题描述】:
折叠列表/数组时对内存使用的影响是什么,以及它与映射列表或数组时的内存使用相比如何(我的意思是执行类似List.map f l 的操作)?
我猜折叠会更昂贵,因为它会在每次迭代时创建“新”结果,并且 map 可以预先分配,但另一方面 map 不是尾递归的。
为简单起见,让我们考虑以下示例:
let lol = List.init 1000 (fun _ -> List.init 1000 (fun j-> j) );;
let fold_left_res = List.fold_left (fun res l -> List.map (fun e -> e + 1) l :: res) lol [] ;;
let map_res = List.map (fun l -> List.map (fun e -> e + 1) l) lol ;;
let fold_right_res = List.fold_right (fun l res -> List.map (fun e -> e + 1) l :: res) lol [];;
使用spacetime我已经对程序进行了剖析并获得了以下结果:
- 列表初始化后:
活动字节:22MB 活动块:1.0M 所有分配的字:3.0M
- fold_left 之后:
与列表初始化后相同(为什么?)
- 地图后
活字节:44MB 活块:2.0M 所有分配的字:6.0M
- fold_right 之后
活动字节:64MB 活动块:3.0M 所有分配的字:9.0M
为什么fold_left 似乎没有保留额外的内存?
为什么lol 首先会消耗这么多内存?
更新1。准备了一个更好的例子。
【问题讨论】: