.net 评测F函数——分析器看不到函数体的任何调用。为什么?

.net 评测F函数——分析器看不到函数体的任何调用。为什么?,.net,performance,f#,profiling,.net,Performance,F#,Profiling,我编写了以下函数 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.M

我编写了以下函数

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,并在我的应用程序上运行了一个非常大的MaxPermission,以确保程序需要一段时间才能运行

这就是我得到的:

正如您所想象的,我实际上想知道的是使用时间是如何分布在getTriangles函数体中的,所以这似乎没有什么特别的帮助。我已经尝试过在构建窗格中关闭代码优化,但它似乎对我没有任何帮助

我做错什么了吗? 我应该如何分析此函数? 这是F或CLR特定的行为吗?
我所有的评测经验都是使用Java的,所以我可能对CLR世界有点陌生。我也涉猎过ANTS性能,但结果是一样的。

我不知道dotTrace,我使用ANTS性能分析器,因为我发现它与F非常有效;我最近一直在使用新版本v8来评测我的项目

在ANTS Performance Profiler中完成评测运行并显示结果后,默认视图仅显示具有源的方法,即正在评测的.exe/.dll旁边有一个.pdb,它指向计算机上的某个有效源位置。您可以使用下拉菜单查看屏幕截图来显示所有方法,这对于F代码非常有用;因为您正在传递函数,所以执行堆栈往往会进出您可能正在使用的库,因此查看所有方法可以更好地了解您的代码实际在做什么,以及来自外部库的代码可能如何影响代码的性能

也就是说-F有两种不同的for循环;它们看起来很相似,但实际上在引擎盖下却大不相同。用于y do中x的循环大致相当于C中的foreach循环——也就是说,循环编译为迭代器,迭代器从某个值序列中提取每个值。第二种更快的循环i=x-to-y-do或i=x-downto-y-do编译成非常简单的IL,就像在C、Java、C等语言中使用for循环一样

这里是函数的一个修改版本,它使用了第二种for循环。在这种情况下,在我的笔记本电脑上,13.749s与13.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还可以为您提供行级计时,但仅限于您有源代码的方法。我编译并分析了您的函数和修改后的版本(MaxPermiture=2000):


我不知道dotTrace,我使用ANTS性能分析器,因为我发现它与F配合得很好;我最近一直在使用新版本v8来评测我的项目

在ANTS Performance Profiler中完成评测运行并显示结果后,默认视图仅显示具有源的方法,即正在评测的.exe/.dll旁边有一个.pdb,它指向计算机上的某个有效源位置。您可以使用下拉菜单查看屏幕截图来显示所有方法,这对于F代码非常有用;因为您正在传递函数,所以执行堆栈往往会进出您可能正在使用的库,因此查看所有方法可以更好地了解您的代码实际在做什么,以及来自外部库的代码可能如何影响代码的性能

也就是说-F有两种不同的for循环;它们看起来很相似,但实际上在引擎盖下却大不相同。用于y do中x的循环大致相当于C中的foreach循环——也就是说,循环编译为迭代器,迭代器从某个值序列中提取每个值。第二种更快的循环i=x-to-y-do或i=x-downto-y-do编译成非常简单的IL,就像在C、Java、C等语言中使用for循环一样

这里是函数的一个修改版本,它使用了第二种for循环。在这种情况下,在我的笔记本电脑上,13.749s与13.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还可以为您提供行级计时,但仅限于您有源代码的方法。我编译并分析了您的函数和修改后的版本(MaxPermiture=2000):


. 看见那里什么都没有。正如我敢说的那样,这两种分析器都只能说明它与.NET framework有关。@EngluseDelysum我不认为这是分析器的问题-当我分析代码以获得第二个屏幕截图时,几乎所有的执行时间都被getTriangles和getTriangles所占用
功能;IIRC,我的版本只调用了一个外部函数,那就是Math.Sqrt——其他所有东西都内联到函数中。但是,如果您真的想查看所有内容,请进入ANTS Performance Profiler中的选项菜单,取消选中隐藏不重要方法的框;探查器运行得比较慢,但它绝对会记录所有内容。@edelysium,如果您不介意的话-请花一点时间将您的屏幕截图发布到。我怀疑右边的NaN值是否应该存在。看见那里什么都没有。正如我敢说的那样,这两种分析器都只能说明它与.NET framework有关。@EngluseDelysum我不认为这是分析器的问题-当我分析代码以获得第二个屏幕截图时,几乎所有的执行时间都被getTriangles和getTriangles函数占用;IIRC,我的版本只调用了一个外部函数,那就是Math.Sqrt——其他所有东西都内联到函数中。但是,如果您真的想查看所有内容,请进入ANTS Performance Profiler中的选项菜单,取消选中隐藏不重要方法的框;探查器运行得比较慢,但它绝对会记录所有内容。@edelysium,如果您不介意的话-请花一点时间将您的屏幕截图发布到。我怀疑右边的NaN值是否应该存在。很明显,所有时间都花在了内部循环的最后三行上,如果没有行级分辨率,探查器不会告诉您。一小部分时间用于各种数学。日常工作。如果没有为它们启用分析功能,它可能不会向您显示这些内容。很明显,所有的时间都花在了内部循环的最后三行上,如果没有行级分辨率,分析程序不会告诉您。一小部分时间用于各种数学。日常工作。如果没有为它们启用评测,它可能不会向您显示这些内容。