Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays F#内存管理_Arrays_Memory Management_Reference_F# - Fatal编程技术网

Arrays F#内存管理

Arrays F#内存管理,arrays,memory-management,reference,f#,Arrays,Memory Management,Reference,F#,在F#中,当在循环中传递数组(递归函数调用自身)时,数组是否放在每个循环的堆栈上(增加内存消耗)?当循环列表或引用对象时,它是如何工作的?您是否可以通过使用ref(references)以某种方式最小化内存消耗?如果您编写尾部递归函数,那么F#将进行尾部调用优化,这样堆栈就不会在每次递归调用中增长 如果您有一个不是尾部递归的函数,您可以使用一种称为延续传递样式的方法,并使用堆而不是堆栈来累积中间值。只要您的函数是尾部递归的,您就不必担心。这仅仅意味着函数所做的最后一件事就是调用它自己。例如: l

在F#中,当在循环中传递数组(递归函数调用自身)时,数组是否放在每个循环的堆栈上(增加内存消耗)?当循环列表或引用对象时,它是如何工作的?您是否可以通过使用ref(references)以某种方式最小化内存消耗?

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


如果您有一个不是尾部递归的函数,您可以使用一种称为延续传递样式的方法,并使用堆而不是堆栈来累积中间值。

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

let rec fact x =
    if x < 1 then 1
    else x * fact (x - 1)
让记录事实x=
如果x<1,则为1
else x*事实(x-1)

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

数组是引用类型,所以当您将它们作为参数传递时,您不会复制或构造数组。如果在递归函数中传递数组,则不会产生空间开销

例如:

let rec loop a i =
  if 0 <= i && i < Array.length a then 
    loop a (a.[i])
  else
    a.[i]
让rec循环一个i=

如果0-1。。。这根本不是尾部递归。在事实(x-1)之后,它的返回值必须乘以x,这使得尾部递归不可能。尾部递归阶乘函数必须使用某种累加值。我的错。这是一个非尾部递归函数的例子。谢谢你的提醒。FixedSo如果函数不是尾部递归的,但是可以通过例如通过另一个线程停止应用程序来停止,那么可以进行的优化是在堆上进行分配,并使用延续传递样式(我将阅读更多内容)?这是否意味着,当指向动态分配内存的指针添加到内存中的另一个指针时,应用程序正在使用的内存正在增长?基本上,如果您可以进行尾部调用优化(因为函数是尾部递归的,所以永远不会使用该值),编译器将这样做。如果这是不可能的,编译器将无法这样做。CPS是一种“强制”尾部递归的方法。不过,这种强制只是将内存从堆栈移动到堆。是的,内存在增长,因为你正在建立一个在以后某个时候需要的状态。在你计算出最终结果之前,数据是gced这是一个可以通过编写这样一个函数来简单回答的问题。是的,这是真的。我需要知道,因为我不知道如何调试f#程序的内存消耗,而且我知道许多函数都是由编译器优化的。所以我想知道,当一个参数为list/array/ref的函数连续循环时,到底发生了什么。如果有人需要知道的话,至少现在在堆栈溢出上很容易找到:)你可以一直使用任务管理器这是真的,我不知道为什么我没有想到这一点。我会试试的。谢谢。值得注意的是,数组将始终位于堆上(数组在.NET中不是值对象),对数组的引用可能是(取决于上下文详细信息)。