2013-04-21 22 views
0

假設我有一個類型爲int - > int的遞歸函數f(x)。 預期越大的x越多,遞歸調用f(x)將執行。在F#中找到堆棧'轉折點'

給定一個遞增順序的無限序列的整數,我對序列中的第一個整數感興趣,當使用f時會導致StackOverflowException。

我該怎麼做?

到目前爲止,我試過做一個簡單的函數,它只是測試在給定的整數上使用給定的函數時是否拋出了StackOverflowException。它看起來像這樣:

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

但是,它似乎無法捕捉StackOverflowException時,它拋出,儘管這是意圖。

有什麼建議嗎?

+1

大問題 - 這取決於函數調用上面有多少個堆棧幀。你爲什麼想知道這個? – 2013-04-21 06:46:27

+0

我有幾個遞歸函數,我想比較一下,看看每個人如何使用堆棧。基本上,要看哪一個能夠處理最大的投入。 – phaz 2013-04-21 06:51:22

+0

您是否可以修改遞歸函數以使用http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx返回堆棧跟蹤? – 2013-04-21 06:54:35

回答

0

捕獲StackOverflowException的替代方法是返回(new StackTrace()).FrameCount,它測量當前的堆棧幀數。

當比較方法時必須注意確保有相同數量的開銷幀。特別是,lambda表達式fun ...將分別添加一個堆棧幀。

1

在.NET 2.0及以上,這是不可能趕上StackOverflowException - 過程只是將被終止:

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

如果你只是在做這個測試的功能,有一種更簡單的方法來獲取所需的信息:編寫一段代碼,將一個計數器(甚至是一個換行符)寫入文本文件,並在每次迭代時調用它。每次寫入文件時,確保在TextWriter(或其他)上調用.Flush(),所以數據實際上是寫入的,而不是緩存的。運行該程序時,它會崩潰(如預期的那樣),但文件中的行數與崩潰之前函數執行的迭代次數相同。