Dado que System.Random es criticado aquí por su "incorrección" y sesgo, me revisé.
distribución
Este código f # demuestra que se comporta realmente bien, en mi máquina promedio:
let r = System.Random()
Seq.init 1000000 (fun _ -> r.Next(0,10))
|> Seq.toList
|> Seq.groupBy id
|> Seq.map (fun (v,ls) -> v, ls |> Seq.length)
|> Seq.sortBy fst
|> Seq.iter (printfn "%A")
(0, 100208)
(1, 99744)
(2, 99929)
(3, 99827)
(4, 100273)
(5, 100280)
(6, 100041)
(7, 100001)
(8, 100175)
(9, 99522)
Las versiones del marco, la máquina y el sistema operativo pueden marcar la diferencia. Ingrese el código en F # interactivo en su máquina y pruébelo usted mismo. Para la cirptografía leí
let arr = [| 0uy |]
let rr = System. Security.Cryptography.RandomNumberGenerator.Create()
Seq.init 1000000 (fun _ -> rr.GetBytes(arr); arr.[0])
|> Seq.toList
|> Seq.groupBy id
|> Seq.map (fun (v,ls) -> v, ls |> Seq.length)
|> Seq.sortBy fst
|> Seq.take 10
|> Seq.iter (printfn "%A")
(0uy, 3862)
(1uy, 3888)
(2uy, 3921)
(3uy, 3926)
(4uy, 3948)
(5uy, 3889)
(6uy, 3922)
(7uy, 3797)
(8uy, 3861)
(9uy, 3874)
actuación
#time
let arr = [| 0uy |]
let r = System.Random()
Seq.init 1000000 (fun _ -> r.NextBytes(arr); arr.[0] |> int64) |> Seq.sum
Real: 00:00:00.204, CPU: 00:00:00.203, GC gen0: 45, gen1: 1, gen2: 1
val it : int64 = 127503467L
let rr = System. Security.Cryptography.RandomNumberGenerator.Create()
Seq.init 1000000 (fun _ -> rr.GetBytes(arr); arr.[0] |> int64) |> Seq.sum
Real: 00:00:00.365, CPU: 00:00:00.359, GC gen0: 44, gen1: 0, gen2: 0
val it : int64 = 127460809L
lo que sugiere una relación 1: 2 y un comportamiento de memoria algo más agradable de la versión criptográfica.
conclusión
Principalmente por su API mucho más agradable, algo por su rendimiento y bastante buena distribución, se prefiere System.Random. System.Random también podría reducir las dependencias de la biblioteca y, si se porta un marco, es probable que System.Random esté disponible antes que la variante Crypto.