在F#中找到堆栈的“临界点”

时间:2013-04-21 06:42:50

标签: f# limit stack-overflow

假设我有一个类型为int的递归函数f(x) - > INT。 预期x越大,f(x)将执行的递归调用越多。

给定一个递增顺序的无限整数序列,我对序列中的第一个整数感兴趣,当它使用f时会导致StackOverflowException。

我该怎么做?

到目前为止,我已经尝试创建一个简单的函数,只测试在给定整数上使用给定函数时是否抛出了StackOverflowException。它看起来像这样:

let overflows f x = 
    try 
        ignore (f x) in false
    with
        | :? System.StackOverflowException -> true

但是,它似乎无法在抛出时捕获StackOverflowException,即使这是意图。

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

在.NET 2.0及更高版本中,捕获StackOverflowException是不可能的 - 该过程将被终止:

http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx

如果你只是这样做来测试函数,那么有一种更简单的方法来获取你想要的信息:编写一些代码,将一个计数器(甚至只是一个换行符)写入文本文件,并在每次迭代时调用它。确保每次写入文件时都在TextWriter(或其他)上调用.Flush(),因此数据实际上是写入的,而不仅仅是缓冲的。当您运行程序时,它会崩溃(如预期的那样),但文件中的行数将与崩溃前函数执行的迭代次数相同。

答案 1 :(得分:1)

您可以尝试使用System.Runtime.CompilerServices.RuntimeHelpers.EnsureSufficientExecutionStack,如果您几乎用完所有筹码,就会抛出一个InsufficientExecutionStackException

答案 2 :(得分:0)

捕获StackOverflowException的另一种方法是返回(new StackTrace()).FrameCount来衡量当前的堆栈帧数。

在比较方法时,必须注意确保有相同数量的开销帧。特别是,lambda表达式fun ...将各自添加一个堆栈帧。