// Using built-in sequence range // (This takes about 3.5-4sec on my machine) let s = seq { for i in 0L .. 10000000L -> i } s |> Seq.length // Using a range generated by an imperative loop // using inline to make this more reusable // (This takes about 0.5sec on my machine) let inline range lo hi = seq { let i = ref lo while i.Value < hi do yield i.Value i.Value <- i.Value + LanguagePrimitives.GenericOne } range 0L 10000000L |> Seq.length // We can make this even faster if we just write the // interface implementation directly. This is ugly, but // it takes some 250ms on my machine... open System.Collections open System.Collections.Generic let inline range2 (lo:^T) (hi:^T) = let one = LanguagePrimitives.GenericOne { new IEnumerable< ^T > with member x.GetEnumerator() = let current = ref (lo - one) { new IEnumerator< ^T > with member x.Current = current.Value interface IEnumerator with member x.Current = box current.Value member x.MoveNext() = if current.Value > hi then false else current.Value <- current.Value + one; true member x.Reset() = current.Value <- lo - one interface System.IDisposable with member x.Dispose() = () } interface IEnumerable with member x.GetEnumerator() = (x :?> IEnumerable< ^T >).GetEnumerator() :> _ } range2 0L 10000000L |> Seq.length