F# 素数の並列計算

あんどーなつ
記事: 171
登録日時: 8年前
連絡を取る:

F# 素数の並列計算

投稿記事 by あんどーなつ » 8年前

関数型言語といえば並列計算、ということで一番簡単そうなやり方で書いてみました。
標準出力をファイルにリダイレクトした場合、実行時間は以下のようになりました。

リアル: 00:00:02.152、CPU: 00:00:09.218、GC gen0: 56, gen1: 52, gen2: 3

実時間よりもCPU時間のほうが長いことに注目してください。単純なスクリプトなので無駄が多いですが、4並列くらいにはなっています。

CODE:

open System.Collections.Concurrent

let segment = 100

let CreatePrimitivePrimes () =
    let mutable lst = [2]
    for i = 3 to segment do
        if (List.forall (fun x -> i % x  0) lst) then lst ()

let lst0to99 = [0..99]

[1..99]
|> List.map ((*) 100)
|> List.map (fun x -> List.map ((+) x) lst0to99)
|> List.map (fun x -> async {
        res.TryAdd(
            List.head x,
            List.filter (fun y -> List.forall (fun z -> y % z  0) p100) x)
        |> ignore
    } )
|> Async.Parallel
|> Async.RunSynchronously
|> ignore

//printfn "%d" (res.Count)
let p10000 = res.Keys
             |> Seq.sort
             |> Seq.map (fun x -> res.[x])
             |> Seq.concat
             |> Seq.toList
             |> List.append p100
res ()

let lst0to9999 = [0..9999]

[1..999]
|> List.map ((*) 10000)
|> List.map (fun x -> List.map ((+) x) lst0to9999)
|> List.map (fun x -> async {
        res.TryAdd(
            List.head x,
            List.filter (fun y -> List.forall (fun z -> y % z  0) p10000) x)
        |> ignore
    } )
|> Async.Parallel
|> Async.RunSynchronously
|> ignore

//printfn "%d" (res.Count)
let p10000000 = res.Keys
                |> Seq.sort
                |> Seq.map (fun x -> res.[x])
                |> Seq.concat
                |> Seq.toList
                |> List.append p10000
//printfn "%A" p10000000
let b = new System.Text.StringBuilder()
List.iter (fun (x : int) -> b.Append(x) |> ignore
                            b.AppendLine() |> ignore)
          p10000000
printfn "%s" (b.ToString())

コメントはまだありません。