F#の範囲演算子が遅かった

コードは、「セクシー素数ベンチ(の非効率な実装)」を移植したもの。

open System.Linq

let isPrime n =  Enumerable.Range(2, n - 2) // {2..n-1}
              |> Seq.forall (fun i -> n % i <> 0)

let sexyPrimes n =  Enumerable.Range(9, n - 8) // {9..n}
                 |> Seq.map (fun i -> [|i-6; i|])
                 |> Seq.filter (fun i -> Array.forall isPrime i)

[<EntryPoint>]
let main args =
    let sw = new System.Diagnostics.Stopwatch()
    sw.Start()
    let c = sexyPrimes 100000 |> Seq.length
    sw.Stop()
    printfn "%A" sw.Elapsed
    printfn "%A" c
    0

Enumerable.Rangeを使うと6秒強で終わる処理なのに、{..}を使うと46秒程度かかってしまう。

rst76が

自分の中で、F#の内包表記は使わないというルールができつつあります。

と書いてたけど、シーケンスの範囲演算子も使わないほうがいいのかな…… どうも、F#が作ってくれるシーケンスが重そうだ(シーケンスが返すEnumeratorが重そう)。

(追記)などとぼやいていたら、殺伐としたTLにMSMVP for VBAF#が登場!

大変参考になりました。ありがとうございましたいげ太さん!