bigint
インデックスでアクセスできるように、任意の整数 (つまり ) をその数字に変換する必要があります。
ただし、アルゴリズムの 2 つの可能な実装の間で迷っていることに気付きました。
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 に接続する必要がありますか? この種のソフトウェア開発のための特別なワークフローはありますか?