簡體   English   中英

分析F#函數 - 分析器看不到函數體的任何調用。 為什么?

[英]Profiling F# function — profiler doesn't see any of the calls of the function's body. Why?

我寫了以下函數

let getTriangles maxPerimeter =
    let mutable count = 0
    for c in 1..maxPerimeter do
        let cc = (int64 (c*c))
        for b in 1..Math.Min(c-1, maxPerimeter-c-1) do
            let bb = (int64 (b*b))
            for a in 1..Math.Min(maxPerimeter-c-b, (int (Math.Ceiling(Math.Sqrt(float (cc+1L-bb)))))) do
                let aa = (int64 (a*a))
                if cc + 1L = aa + bb then
                    count <- count + 1
    count

現在是時候調整它了。

為此,我安裝了dot Trace Performance並在我的應用程序上運行了一個非常大的maxPerimeter ,以確保程序需要一段時間才能運行。

這就是我得到的:

在此輸入圖像描述

正如您可能想象的那樣,我實際想知道的是如何 getTriangles'函數體內分配使用時間,所以這似乎沒有特別的幫助。 我已經嘗試在“ Build窗格中關閉代碼優化,但它似乎對我沒有幫助。

  1. 難道我做錯了什么?
  2. 我應該如何分析這個功能?
  3. 這是F#還是CLR特有的行為?

我擁有的所有分析經驗都是使用Java,因此我可能會對CLR世界有所了解。 我也涉足ANTS Performance,但結果是一樣的。

我不知道dotTrace,我使用ANTS Performance Profiler,因為我發現它與F#的效果非常好; 我最近一直在使用新版本(v8)來分析我的fsharp-tools項目。

在ANTS Performance Profiler中完成分析運行並顯示結果后,默認視圖僅顯示您擁有源的方法(即,您正在分析的.exe / .dll旁邊有一個.pdb,它指向您計算機上的某個有效源位置)。 您可以使用下拉列表(請參見屏幕截圖)顯示所有方法,這對F#代碼非常有用; 因為您正在傳遞函數,執行堆棧往往會進出您可能正在使用的庫,因此查看“所有方法”可以更好地了解代碼實際執行的操作以及外部庫中的代碼可能會影響代碼的性能。

ANTS Performance Profiler v8截圖,分析F#代碼(fsharp-tools)

那說 - F#有兩種不同的for循環; 它們看起來很相似,但實際上卻完全不同。 你使用的那個( for x in y do )大致相當於C#中的foreach循環 - 也就是說,循環編譯成一個迭代器,它從某個值序列中提取每個值。 第二種,更快的循環( for i = x to y do或者for i = x downto y do )編譯成非常簡單的IL,就像你在C#,Java,C等中使用for循環一樣。

這是你的函數的修改版本,它使用第二種for循環。 在這種情況下,它只是稍微快一點( 13.749s13.520s ,我的筆記本電腦N = 5000 ),但如果你在數字范圍內進行任何緊密循環,那么毫無疑問你想要編寫代碼的方式。

let getTriangles' maxPerimeter =
    let mutable count = 0
    for c = 1 to maxPerimeter do
        let cc = int64 (c * c)
        for b = 1 to min (c-1) (maxPerimeter-c-1) do
            let bb = int64 (b * b)
            for a = 1 to min (maxPerimeter-c-b) (int <| ceil (sqrt <| float (cc+1L-bb))) do
                let aa = int64 (a * a)
                if cc + 1L = aa + bb then
                    count <- count + 1
    count

就功能中的行為而言,ANTS Performance Profiler還可以為您提供行級時序(但僅適用於您擁有源的方法)。 我編譯並分析了你的函數和我的修改版本( maxPerimeter = 2000 ):

ANTS Performance Profiler v8,F#項目的行級時序

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM