RunSynchronously成本 [英] Cost of RunSynchronously

查看:109
本文介绍了RunSynchronously成本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是为什么下面两个定时不同,如此大幅度的原因是什么?

What are the reasons why the two timings below differs so dramatically ?

     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();}

注:如果我改变pinitilized到10 $ P $的数字,它不会改变任何东西。
在屏幕上的对象池接收消息,当它积累(慢)获得卡斯特之前发生的缓慢

NB : if I change the number of preinitilized to 10, it does not change anything. The slowness occurs before receiving the message in the object pool, when it accumulates (slowly) 'acquiring cust' on the screen

推荐答案

尝试把它在一个循环:

for i in 1..5 do 
    time acquire  //   76 ms 
    time acquire2 // 5310 ms 

我觉得你只是目睹了最初的时间来热身线程池(只喜欢两人均默认为第二添加两个线程);一旦它是温暖的,事情很快。

I think you are just witnessing the initial time to warm up the threadpool (which only likes two add two threads per second by default); once it is warm, things are fast.

这篇关于RunSynchronously成本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆