【问题标题】:how does building a big task computation compare to execute synchronously several steps?构建一个大任务计算与同步执行几个步骤相比如何?
【发布时间】:2018-10-04 18:01:38
【问题描述】:

我有以下两段用 Scala/Monix 编写的代码:

def f1(input) =
  for {
    a <- task1(input)
    b <- task2(a)
    c <- task3(b)
  } yield (c).runSyncUnsafe

def f2(input) = {
  val a = task1(input).runSyncUnsafe
  val b = task2(a).runSyncUnsafe
  task3(b).runSyncUnsafe
}

我认为 f1 版本更好,因为它完全异步并且不会阻塞线程,我的假设是,如果有很多任务正在运行,第一个应该在多线程中表现更好。

我知道我应该编写一个测试来比较这两种实现,但这需要对遗留代码进行大量重构。此外,在我们的具体情况下,这两个版本的分析并不容易,所以我先在这里问,希望有很多 Scala/Monix 经验的人回答:

两者在重负载下的性能应该如何比较?这是一个真正的问题还是无关紧要?

【问题讨论】:

    标签: scala asynchronous monix


    【解决方案1】:

    作为一般规则,最好尽可能长时间地保持异步。所以你可以这样写f1

    def f1(input) =
      for {
        a <- task1(input)
        b <- task2(a)
        c <- task3(b)
      } yield c
    

    然后,调用者可以决定是调用 runSyncUnsafe 还是异步调用(runAsyncrunOnComplete)或 flatMap 执行另一个任务。这会从您的代码中删除 Unsafe 调用,并将其留给调用者来决定是否安全。

    就性能而言,无论哪种方式,任务都将按顺序进行评估,因为后面的任务取决于前面任务的结果。

    【讨论】:

    • 我关心的是,如果线程在运行 runSyncUnsafe 时被阻塞,那么运行时就不能在其他计算中使用它,而如果你保持异步等待不会阻塞,所以运行时可以使用所有线程跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-21
    相关资源
    最近更新 更多