System.Random이 "부정확성"과 편견 때문에 여기에서 부끄러워 졌기 때문에 저는 스스로 확인했습니다.
분포
이 f # 코드는 내 평균적인 컴퓨터에서 정말 멋지게 작동 함을 보여줍니다.
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)
프레임 워크 버전, 시스템, 운영 체제는 모두 차이를 만들 수 있습니다. 컴퓨터에서 대화 형 F #으로 코드를 입력하고 직접 시도해보세요. Cyrptography를 위해 나는 읽었다
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)
공연
#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
이는 1 : 2 관계와 암호화 버전의 다소 좋은 메모리 동작을 제안합니다.
결론
주로 훨씬 더 좋은 API, 성능 및 배포가 상당히 우수한 System.Random이 선호됩니다. System.Random은 또한 라이브러리 종속성을 줄일 수 있으며 프레임 워크가 포팅 된 경우 System.Random은 Crypto 변형보다 먼저 사용할 수 있습니다.