1
以下兩種時間差異如此顯着的原因是什麼?運行成本同步
let time acquire =
let sw = System.Diagnostics.Stopwatch.StartNew()
sw.Start()
let tsks = [1 .. 10] |> Seq.map (fun x -> acquire)
let sec = Async.RunSynchronously(Async.Parallel tsks)
sw.Stop()
printfn "Generation time %A ms" sw.Elapsed.TotalMilliseconds
sw.Reset()
Console.ReadKey() |> ignore
let custPool = ObjectPool(customerGenerator, 0)
let acquire = async { printfn "acquiring cust" ; return! custPool.Get() }
let acquire2 = async { return Async.RunSynchronously(acquire)}
time acquire // 76 ms
time acquire2 // 5310 ms
我用下面
type ObjectPool<'a>(generate: unit -> 'a, initialPoolCount) =
let initial = List.init initialPoolCount (fun (x) -> generate())
let agent = Agent.Start(fun inbox ->
let rec loop(x) = async {
let! msg = inbox.Receive()
match msg with
| Get(reply) -> let res = match x with | a :: b -> reply.Reply(a);b
| [] as empty-> reply.Reply(generate());empty
printfn "gave one, %A left" (Seq.length res)
return! loop(res)
| Put(value) -> printfn "got back one, %A left" ((Seq.length x) + 1)
return! loop(value :: x)
| Clear(reply) -> reply.Reply x
return! loop(List.empty<'a>)
}
loop(initial))
/// Clears the object pool, returning all of the data that was in the pool.
member this.ToListAndClear() = agent.PostAndAsyncReply(Clear)
/// Puts an item into the pool
member this.Put (item) = agent.Post(item)
/// Gets an item from the pool or if there are none present use the generator
member this.Get (item) = agent.PostAndAsyncReply(Get)
type Customer = {First : string; Last : string; AccountNumber : int;} override m.ToString() = sprintf "%s %s, Acc: %d" m.First m.Last m.AccountNumber
let names,lastnames,rand = ["John"; "Paul"; "George"; "Ringo"], ["Lennon";"McCartney";"Harison";"Starr";],System.Random()
let randomFromList list= let length = List.length list
let skip = rand.Next(0, length)
list |> List.toSeq |> (Seq.skip skip) |> Seq.head
let customerGenerator() = { First = names |> randomFromList;
Last= lastnames |> randomFromList;
AccountNumber = rand.Next();}
NB對象池:如果我改變的preinitilized到10號,它不會改變任何東西。在屏幕上的對象池接收消息,當它積累(慢)「獲得卡斯特」之前發生 的緩慢
有意思。當我調用RunSynchronously時,我的印象是它可以重用當前的線程池。 – nicolas 2012-04-01 11:17:07
F#異步使用ThreadPool。只是.NET ThreadPool從小處開始,並且限制它分配更多線程的速度,以避免在排隊項目活動異常點突發上浪費資源。 – Brian 2012-04-01 22:33:07
謝謝我忘了發佈更新。你是對的,我現在增加了一個setminthread。開始我的項目我從來都不會想到我會深入這個領域,但這確實很有意義。 THKS – nicolas 2012-04-01 22:38:14