Следующий код показал, что генерация последовательности с использованием выражения последовательности, содержащего for
, была примерно в пять раз быстрее, чем генерация той же последовательности, используя Seq.init
.
open System
let rand count =
let rnd = Random() // if this value is not created all numbers are equal
seq {for i in 0..(count - 1) -> rnd.NextDouble()}
/// Perhaps more "functional" than rand but slower
let rand2 count =
let rnd = Random()
let rnd2 (i: int) = rnd.NextDouble()
Seq.init count rnd2
> rand 1000000 |> List.ofSeq |> List.head;;
Real: 00:00:00.092, CPU: 00:00:00.093, GC gen0: 3, gen1: 2, gen2: 0
val it : float = 0.1358240168
> rand2 1000000 |> List.ofSeq |> List.head;;
Real: 00:00:00.473, CPU: 00:00:00.484, GC gen0: 21, gen1: 20, gen2: 1
val it : float = 0.4128856414
Вопросы:
1) В чем причина разницы в скорости?
2) Является ли альтернатива Seq.init
в некотором смысле "более функциональной", чем альтернатива последовательности?
3) Являются ли две альтернативы эквивалентными с точки зрения безопасности потоков?