【问题标题】:Good F# Performance Profiling Tool良好的 F# 性能分析工具
【发布时间】:2011-12-19 14:22:18
【问题描述】:

谁能推荐一个具有良好 F# 支持的性能分析工具?

我一直在使用 Visual Studio 2010 分析器,但在使用 F# 时发现了一些问题。感觉更像是我在分析反射后的字节码,而不是原来的 F#。

例如,在分析以下稍微做作的示例时:

let Add a b = 
    a + b

let Add1 = Add 1

let rec MultiAdd count = 
    match count with
    | 1 -> 1
    | _ -> (Add1 1) + (MultiAdd (count - 1))

MultiAdd 10000 |> ignore

我得到以下调用树:

当我在函数详细信息中查看 Microsoft.FSharp.Core.FSharpFunc`2.Invoke(0) 时,我看到:

我知道我所看到的是基于编译代码的底层实现,虽然我可以遵循它,但很难做到。

有没有人有使用 F# 的其他分析工具的经验,他们在映射到原始 F# 代码方面做得更好吗?

【问题讨论】:

  • 您是否尝试过 CPU 采样选项而不是函数调用的检测?
  • 我最近没有看过这个,所以我不能说现在最好的选择是什么,但当时我使用 dotTrace 并且刚刚习惯使用生成的反编译代码 dotTrace。跟踪所有的 '.Invoke()' 调用实际上对于诊断性能问题非常有用,因为它向您展示了幕后真正发生的事情。一般来说,反编译的代码越复杂,运行速度就越慢。

标签: performance f# profiling


【解决方案1】:

我的回答可能会让你失望,但可能会有所帮助。

几个月前,我试图为我的 F# 项目找到一个好的免费 .NET 分析器。我对nprofslimtuneEQATEC 和(最近的商业)Xte profiler 的体验一点也不像样。我发现他们对 F# 的支持非常有限,不得不退回到 Visual Studio 2010 profiler。我认为你最好的选择是一些商业分析器(我没有经验)。

一段时间后,我习惯了分析器,并看到它的结果呈现简单、清晰且易于理解。如果您正在优化并行程序,则使用 Concurrent Visualizer 将是不可避免的。也就是说,您只关心性能;与 VS 2010 profiler 相处得很好值得一试。

对于分析 F# 代码,我还发现 CLR ProfilerILSpy 值得一提。如果您想最小化内存分配或垃圾收集,前者可以可视化堆。后者可以在 IL 或 C# 中生成等效代码(我比 F# 更熟悉);它可能有助于理解 F# 中的高阶构造是如何工作的,以便适当地使用它们。

更新:

Dave Thomas 写过an excellent blog post,他在其中使用了几个商业分析器来检测内存泄漏和调整异步应用程序。看看那些分析器;它们可能适合您的喜好。

【讨论】:

  • 感谢您的提及!主要问题是将名称映射回 F# 类型,检查 jetbrains.com/profiler 的评估,如果有一个“代码行”选项,可以让您分析到有问题的行
【解决方案2】:

这听起来像是您在调试模式下的分析。您需要从项目 -> 属性 -> 构建菜单中启用“优化代码”。您还可以在默认情况下启用此功能的发布模式下进行概要分析。如果你不这样做,将会有很多调用调用和元组对象创建等等。

上面的 MultiAdd 函数不是尾递归的。如果是这样,您还需要在调试模式下启用“生成尾调用”以进行分析。

这也是尾调用优化的好案例。

let Add a b = 
    a + b

let Add1 = Add 1

let rec MultiAdd total count =
    match count with
    | 1 -> 1 + total
    | _ -> MultiAdd (count - 1) (total + Add1 1)

MultiAdd 10000 0 |> ignore

【讨论】:

  • 我尝试在发布模式下运行它并确保选中“优化代码”但仍然得到相同的结果。我错过了什么吗?
  • @KeithHarrison 在这种情况下调用不会消失,因为这个函数不是尾递归的。试试我添加的尾调用版本。调试器还具有降噪滤波器。您可以将其设置为忽略低于 % 时间的调用。
最近更新 更多