(F#) Concurrent Queue, Stack and Bag and Dictionary のメモ


Summray

Concurrent Queue, Stack and Bag and Dictionary のメモ

ConcurrentQueue

open System.Collections.Concurrent

// ConcurrentQueue クラスは
// thread-safe な queue(FIFO) コレクション
let cq = new ConcurrentQueue<int>()

// Enqueue
[0..9999] |> List.iter cq.Enqueue

// Dequeue
let dequeue = async {
    let mutable subTotal = 0
    while not cq.IsEmpty do
        subTotal <- subTotal + ( cq.TryDequeue() |> snd )
    return subTotal
}

List.init 10 ( fun _ -> dequeue )   // dequeueを10個つくる
|> Async.Parallel                   // パラレルで処理をする
|> Async.StartAsTask                // タスクとして実行
|> fun x -> x.Result                // タスクの結果をとりだす [|13859507; 8933578; 0; 14053043; 0; 0; 13148872; 0; 0; 0|]
|> Array.sum                        // それぞれのタスクの結果を合計する
|> printfn "%A"                     // 結果 49995000

ConcurrentStack

open System.Collections.Concurrent

// ConcurrentStack クラスは
// thread-safe な queue(LIFO) コレクション
let cs = new ConcurrentStack<int>()

// Push
[0..9999] |> List.iter cs.Push

// Pop
let dequeue = async {
    let mutable subTotal = 0
    while not cs.IsEmpty do
        subTotal <- subTotal + ( cs.TryPop() |> snd )
    return subTotal
}

List.init 10 ( fun _ -> dequeue )   // dequeueを10個つくる
|> Async.Parallel                   // パラレルで処理をする
|> Async.StartAsTask                // タスクとして実行
|> fun x -> x.Result                // タスクの結果をとりだす [|13859507; 8933578; 0; 14053043; 0; 0; 13148872; 0; 0; 0|]
|> Array.sum                        // それぞれのタスクの結果を合計する
|> printfn "%A"                     // 結果 49995000

ConcurrentBag

open System.Collections.Concurrent

// ConcurrentBag クラスは
// thread-safe な non-order コレクション
let cb = new ConcurrentBag<int>()

// Add
[0..9999] |> List.iter cb.Add

// Take
let dequeue = async {
    let mutable subTotal = 0
    while not cb.IsEmpty do
        subTotal <- subTotal + ( cb.TryTake() |> snd )
    return subTotal
}

List.init 10 ( fun _ -> dequeue )   // dequeueを10個つくる
|> Async.Parallel                   // パラレルで処理をする
|> Async.StartAsTask                // タスクとして実行
|> fun x -> x.Result                // タスクの結果をとりだす [|13859507; 8933578; 0; 14053043; 0; 0; 13148872; 0; 0; 0|]
|> Array.sum                        // それぞれのタスクの結果を合計する
|> printfn "%A"                     // 結果 49995000

ConcurrentDictionary

こんな感じ


open System.Collections.Generic
open System.Collections.Concurrent

let dic : ConcurrentDictionary<string,int> = new ConcurrentDictionary< string, int >()

// appleははじめてなので 100
dic.AddOrUpdate("apple",100, fun _ price -> price + 99 )
dic.Values |> printfn "%A" // seq [100]

// appleは2回目のなので 100 + 99
dic.AddOrUpdate("apple",100, fun _ price -> price + 99 )
dic.Values |> printfn "%A" // seq [199]

// appleはすでに登録されているので 199
dic.GetOrAdd("apple",999)
|> printfn "%A" // 199

// bananaははじめてなので 9999
dic.GetOrAdd("banana",9999)
|> printfn "%A" // 9999

// cherryははじめてなので 99999
dic.GetOrAdd( "cherry", fun _ -> 99999)
|> printfn "%A" // 99999


dic.Keys |> printfn "%A"
// seq ["banana"; "cherry"; "apple"]

dic.Values |> printfn "%A"
// seq [9999; 99999; 199]

dic.Item("cherry") |> printfn "%A" // 99999

dic.ContainsKey("apple") |> printfn "%A" // true

dic.Count |> printfn "%A" // 3

dic.ToArray() |> printfn "%A"
// [|[banana, 9999]; [cherry, 99999]; [apple, 199]|]

dic |> printfn "%A"
// seq [[banana, 9999]; [cherry, 99999]; [apple, 199]]