Async vs sync benchmark

728 篇文章 1 订阅
38 篇文章 0 订阅
文章来自: http://fssnip.net/cQ

Async vs sync benchmark

Quick benchmark to compare the throughput performance of F# MailboxProcessor using asynchronous workflows and a synchronous agent using a lock and busy loop. The latter is 9x faster on this machine.


type Message<'a> =
  | Enqueue of 'a
  | Dequeue of (seq<'a> -> unit)

while true do
  do
    let n = 1000000
    let agent =
      MailboxProcessor.Start(fun inbox ->
        let msgs = Array.zeroCreate n
        let i = ref 0
        let rec loop() =
          async { let! msg = inbox.Receive()
                  match msg with
                  | Enqueue x ->
                      msgs.[!i] <- x
                      incr i
                      return! loop()
                  | Dequeue reply ->
                      reply msgs }
        loop())
    let timer = System.Diagnostics.Stopwatch.StartNew()
    for i=1 to n do
      agent.Post(Enqueue i)
    agent.PostAndReply(fun reply -> Dequeue reply.Reply)
    |> ignore
    printfn "%f msgs/s" (float n / timer.Elapsed.TotalSeconds)

  do
    let n = 1000000
    let queue = ResizeArray()
    use barrier = new System.Threading.Barrier(2)
    System.Threading.Thread(fun () ->
      let msgs = Array.zeroCreate n
      let i = ref 0
      let msg = ref Unchecked.defaultof<_>
      let rec loop() =
        let xs = lock queue (fun () -> let xs = queue.ToArray() in queue.Clear(); xs)
        let rec iter j =
          if j = xs.Length then loop() else
            match xs.[j] with
            | Enqueue x ->
                msgs.[!i] <- x
                incr i
                iter (j+1)
            | Dequeue reply ->
                reply msgs
                barrier.SignalAndWait()
        iter 0
      loop()).Start()
    let timer = System.Diagnostics.Stopwatch.StartNew()
    for i=1 to n do
      lock queue (fun () -> queue.Add(Enqueue i))
    let msgs = ref Seq.empty
    lock queue (fun () -> queue.Add(Dequeue(fun xs -> msgs := xs)))
    barrier.SignalAndWait()
    let t = timer.Elapsed.TotalSeconds
    printfn "%f msgs/s" (float(Seq.length !msgs) / t)


=========

625399.121902 msgs/s
1642304.448756 msgs/s
669976.394722 msgs/s
3847811.364896 msgs/s
639158.928210 msgs/s
3660838.002427 msgs/s
708897.033486 msgs/s
2027123.315385 msgs/s
829547.417179 msgs/s
2680050.481431 msgs/s
798219.842037 msgs/s
2437920.785128 msgs/s
723579.420041 msgs/s
2066545.236469 msgs/s
747327.575274 msgs/s
3910371.164610 msgs/s
713527.133011 msgs/s
3603749.052214 msgs/s
699356.647833 msgs/s
2444600.464279 msgs/s
801463.472300 msgs/s
2720499.178953 msgs/s
502640.470922 msgs/s
2190322.367265 msgs/s
645807.973261 msgs/s
2480027.716790 msgs/s

==========

    后面的确实比前面的快,但没有文章说的那么快。也就是 4~5 倍。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值