下面两个时间差异如此显着的原因是什么?
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();}
注意:如果我将preinitilized的数量改为10,它不会改变任何东西。 在对象池中接收消息之前,当它在屏幕上累积(缓慢)“获取cust”时,会发生缓慢
答案 0 :(得分:2)
尝试将其置于循环中:
for i in 1..5 do
time acquire // 76 ms
time acquire2 // 5310 ms
我认为你只是看到了预热线程池的初始时间(默认情况下,它只需要每秒添加两个线程);一旦它变暖,事情就会很快。