我正在通过使用F#脚本自动化一些任务来学习F#。我从命令行使用“ fsi / fsarpi --exec”运行此脚本。我正在使用.Net core进行工作。我要寻找的一件事是如何分析我的F#脚本。我主要是在寻找
总体而言,我试图了解我的脚本的性能瓶颈。
另一方面,有没有办法将F#脚本编译为exe?
答案 0 :(得分:4)
我建议将BenchmarkDotNet用于所有基准测试任务(嗯,微基准测试)。由于它是一种统计工具,因此它可以解决手动基准测试无法解决的许多问题。只需应用一些属性,您就可以得到一个漂亮的报告。
创建一个.NET Core控制台应用程序,添加BenchmarkDotNet程序包,创建一个基准,然后运行它以查看结果。这是一个示例,测试两个简单的解析函数,其中一个作为比较基准,并通知BenchmarkDotNet在运行基准测试时捕获内存使用情况统计信息:
open System
open BenchmarkDotNet.Attributes
open BenchmarkDotNet.Running
module Parsing =
/// "123,456" --> (123, 456)
let getNums (str: string) (delim: char) =
let idx = str.IndexOf(delim)
let first = Int32.Parse(str.Substring(0, idx))
let second = Int32.Parse(str.Substring(idx + 1))
first, second
/// "123,456" --> (123, 456)
let getNumsFaster (str: string) (delim: char) =
let sp = str.AsSpan()
let idx = sp.IndexOf(delim)
let first = Int32.Parse(sp.Slice(0, idx))
let second = Int32.Parse(sp.Slice(idx + 1))
struct(first, second)
[<MemoryDiagnoser>]
type ParsingBench() =
let str = "123,456"
let delim = ','
[<Benchmark(Baseline=true)>]
member __.GetNums() =
Parsing.getNums str delim |> ignore
[<Benchmark>]
member __.GetNumsFaster() =
Parsing.getNumsSpan str delim |> ignore
[<EntryPoint>]
let main _ =
let summary = BenchmarkRunner.Run<ParsingBench>()
printfn "%A" summary
0 // return an integer exit code
在这种情况下,结果将显示getNumsFaster
函数分配0字节并以大约33%的速度运行。
一旦发现性能一致且分配较少的东西,就可以将其转移到实际执行代码的脚本或其他环境中。
对于热点,最好的工具是在PerfView之类的探查器下实际运行脚本,并在脚本执行时查看CPU时间和由脚本引起的分配。这里没有简单的答案:正确解释性能分析结果是一项艰巨且耗时的工作。
无法将F#脚本编译为.NET Core的可执行文件。仅在Windows / .NET Framework上才有可能,但这是不推荐使用的旧行为。如果您希望将脚本中的代码作为可执行文件运行,建议将其转换为应用程序。