返回Future.failed(Exception)和抛出异常之间的区别

jnf*_*nfr 10 scala

在Scala中,返回Future.failed(new Exception("message!"))throw new Exception("message!")?之间的区别是什么?

假设这是在要返回的函数中发生的Future[Unit],并且调用函数是这样的:

someFunction onFailure {
  case ex: Exception => log("Some exception was thrown")
}
Run Code Online (Sandbox Code Playgroud)

是否有一个优先于另一个或每个特定用例?

Ben*_*ich 11

调用Future { throw ex }Future.failed(ex)将创建一个相同的结果.但是,使用Future.failed效率更高.如果我们从Future.apply(来自此处)中查看此片段:

promise complete {
    try Success(body) catch { case NonFatal(e) => Failure(e) }
}
Run Code Online (Sandbox Code Playgroud)

我们注意到(正如可以预料的那样),它依赖于一个try...catch块.与普通代码相比,这些已知会带来很大的开销.该Future.failed方法本质上是一个快捷方式,而不必承担实际抛出异常的成本.

  • 其实让我在这里纠正自己.**使用'Future {throw ex }`而不是`Future.failed(ex)`,**是一个显着的性能损失,尽管如我所说,它本身与异常处理几乎没有关系.罪魁祸首实际上是`Future.apply`在`ExecutionContext`上执行(而`Future.failed`直接返回完成的`Future`),因此这会产生一个显着的额外延迟(`Future`将在未来的某些方面,加上上下文切换的影响).所以是的,`Future.failed(ex)`的性能明显更高. (9认同)
  • 实际上,异常处理的大部分开销来自异常的实例化(因为它们 - 默认情况下 - 捕获堆栈,这非常昂贵).因为你要以任何一种方式实例化异常(无论你使用`Future.failed`还是`Future {throw ex}`),那部分都不会输入等式.这只留下实际的投掷/捕获机制.它肯定有成本,但它首先由创建异常的成本占主导地位,因此在实践中使用任何一种风格都无关紧要. (4认同)