我需要将任意整数(即bigint
)转换为其数字,这样我就可以通过索引访问它们。
不过,我发现自己在算法的两种可能实现之间徘徊:
open System
let toDigits (x:bigint) =
x.ToString()
|> Seq.map (fun c -> (int c) - (int '0'))
|> Seq.toArray
let toDigits' (x:bigint) =
seq {
let x' = ref x
while !x' <> 0I do
yield (int (!x' % 10I))
x' := !x' / 10I
} |> Seq.toArray |> Seq.rev
我喃喃自语哪一个最快?为了帮助我回答这个问题,我设计了一个简单的profile
方法
let profile f times =
let x = ref 0
while !x < times do
incr x
f (bigint !x) |> ignore
当与 F# Interactive 合并时#time
产生以下输出:
> profile toDigits 10000000;;
Real: 00:00:11.609, CPU: 00:00:11.606, GC gen0: 825, gen1: 1, gen2: 0
val it : unit = ()
> profile toDigits' 10000000;;
Real: 00:00:28.891, CPU: 00:00:28.844, GC gen0: 1639, gen1: 3, gen2: 0
val it : unit = ()
这清楚地表明了toDigit
'的优越性。不过,我想知道为什么,所以我问我的 F# 溢出者从现在开始我应该怎么做。
在一个典型的 Java 程序中,我只需启动一个分析器(例如 jvisualvm)并让它告诉我在某种 CPU 采样视图中哪些是热门方法。我想这与我在常规项目中使用 .fs 文件进行开发的方式完全相同。当我在 F# Interactive 中时,我有点迷茫。我应该将 .NET 分析器(在本例中为 ANTS 内存分析器)附加到 F# Interactive 吗?这种软件开发有什么特殊的工作流程吗?