Puisque System.Random est critiqué ici pour son "inexactitude" et son biais, je me suis vérifié.
Distribution
Ce code f # démontre qu'il se comporte vraiment bien - sur ma machine moyenne:
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)
Les versions du framework, la machine, le système d'exploitation peuvent tous faire la différence. Entrez le code en F # interactif sur votre machine et essayez vous-même. Pour la cyrptographie j'ai lu
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)
performance
#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
ce qui suggère une relation 1: 2 et un comportement mémoire un peu plus agréable de la version crypto.
conclusion
Principalement pour son API beaucoup plus agréable, un peu pour ses performances et une assez bonne distribution, System.Random est préféré. System.Random peut également réduire les dépendances de bibliothèque et si un framework est porté, System.Random sera probablement disponible avant la variante Crypto.