F#内存管理

F# memory management

在 F# 中,当您在循环中传递数组(递归函数调用自身)时,数组是否会在每个循环中放入堆栈(增加内存消耗)?循环时如何处理列表或引用对象?你能以某种方式最小化内存消耗吗,也许通过使用 ref(引用)?

如果您编写尾递归函数,那么 F# 将进行尾调用优化,这样堆栈就不会在每次递归调用中增长。

如果你有一个非尾递归的函数,你可以使用一种称为连续传递风格的东西,并使用堆而不是堆栈来累积中间值。

只要您的函数是尾递归的,您就不必担心。这仅仅意味着你的函数做的最后一件事就是调用它自己。示例:

let rec fact x =
    if x < 1 then 1
    else x * fact (x - 1)

这个函数在 (x - 1) 之后乘以 x,所以它不是尾递归的。

数组是引用类型,因此当您将数组作为参数传递时,您并不是在复制或构造数组。如果您在递归函数中传递数组,则不会产生 space 开销。

例如:

let rec loop a i =
  if 0 <= i && i < Array.length a then 
    loop a (a.[i])
  else
    a.[i]

这个函数在数组中跳转,直到它找到一个不是数组索引的值。假设尾调用优化,它没有 space-开销,即它不分配任何东西。