【问题标题】:When using Scala futures, will chained callbacks with the same execution context be optimised into synchronous calls?使用 Scala 期货时,具有相同执行上下文的链式回调是否会被优化为同步调用?
【发布时间】:2013-11-16 15:57:29
【问题描述】:

Scala 2.10 中的新 Future 对异步调用操作的每个操作(包括 mapfilter 等)使用执行上下文。这是否意味着每个动作都将始终通过执行上下文单独调用,或者当链接多个转换/过滤器​​时,这一步是否可能被优化掉?每个使用相同的执行上下文?

即如果在执行f.map(...).filter(...).map(...) 时,都具有相同的执行上下文,这将调用execute() 一次(因为它足够聪明,可以从上面组合一个同步函数),还是三次?

如果 scala 未来不做上述优化,是否有更适合做上述优化的长链组合的替代框架?

【问题讨论】:

    标签: scala future scala-2.10


    【解决方案1】:

    我无法提供任何可以清楚说明实际情况的文档链接,但我们可以进行一个简单的实验来回答您的问题。

    只需打开 Scala REPL 并粘贴以下代码:

    import java.util.concurrent.Executors
    import scala.concurrent._
    
    implicit val ec = new ExecutionContext {
        val threadPool = Executors.newFixedThreadPool(1000);
    
        def execute(runnable: Runnable) {
            threadPool.submit(runnable)
            println("execute!")
        }
    
        def reportFailure(t: Throwable) {}
    }
    
    future { 1 } map(_ + 1) filter (_ > 0) map (_ + 2) 
    

    它将打印:

    scala> 未来 { 1 } 映射(_ + 1)过滤器(_ > 0)映射(_ + 2)
    执行!
    执行!
    执行!
    执行!
    res0: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise$DefaultPromise@7ef3de76

    因此,您正在执行的每个操作都会调用 execute(您可以在文档中查看每个函数,如 map 或 filter,都将 ExecutionContext 作为隐式参数:http://www.scala-lang.org/api/2.10.6/#scala.concurrent.Future

    如果您正在寻找替代框架,您应该查看 scalaz Futures。我对他们没有经验,但他们似乎是你正在寻找的。检查此线程:https://groups.google.com/forum/#!msg/scalaz/-PuakIf-g_4/7ydrU5VIfDQJ

    与 scala 2.10 中的 Future 实现不同,mapflatMap 不会产生新任务,也不需要隐式 ExecutionContext。相反,mapflatMap 只是添加到将由“当前”线程运行的当前(蹦床)延续,除非通过Future.forkFuture.apply 明确分叉。这意味着Future 实现了比 2.10 实现更好的线程重用,并避免了不必要的线程池提交周期。

    Future 也不同于 scala 2.10 Future 类型,因为它不一定代表 正在运行 计算。相反,我们使用scalaz.Nondeterminsm 接口的函数明确重新引入了不确定性。这简化了我们的实现并使代码更易于推理,因为效果的顺序和不确定性点已完全明确,并且不依赖于 Scala 的评估顺序。

    重要提示:Future 不包括任何错误处理,并且通常只能由希望在Future 的功能上构建但希望设计自己的错误处理策略的库编写者用作构建块。请参阅 scalaz.concurrent.Task 以了解扩展 Future 并具有适当错误处理的类型——它只是 Future[Either[Throwable,A]] 的包装器,具有许多额外的便利功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-22
      • 1970-01-01
      • 2015-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-16
      • 2021-04-19
      相关资源
      最近更新 更多