Den*_*VDB 3 performance functional-programming scala scalaz
我有两个monad实例val a: M[A]和val b: M[B].在以下代码情况下会有任何性能差异吗?
def f: (A, B) => C
val applicativeCombine = (a |@| b)(f)
val monadCombine =
for {
aa <- a
bb <- b
} yield f(aa, bb)
Run Code Online (Sandbox Code Playgroud)
......还是依赖?
如果a并且b是返回期货并执行一些计算上昂贵的操作的方法,则applicativeCombine版本将并行运行它们,而monadCombine不是,这意味着|@|可能接近两倍的速度.
如果a和b是期权,另一方面,甚至期货没有被做计算成本的工作,这是可能的for版本可能会更快,因为它的脱糖形式涉及一对夫妇少分配:
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> showCode(reify((Option(1) |@| Option(2))(_ + _)).tree)
res0: String = Scalaz.ToApplyOps(Option.apply(1))(Scalaz.optionInstance).|@|(Option.apply(2)).apply(((x$1, x$2) => x$1.+(x$2)))(Scalaz.optionInstance)
scala> showCode(reify(for { a <- Option(1); b <- Option(2) } yield a + b).tree)
res1: String = Option.apply(1).flatMap(((a) => Option.apply(2).map(((b) => a.+(b)))))
Run Code Online (Sandbox Code Playgroud)
(但这不太可能在大多数程序中产生有意义的差异.)
如果这是Cats和the a和beithers并且你有"错误"的导入,那么你得到FlatMapSyntax而EitherInstances不是EitherSyntax,而|@|版本可能会再次更快,因为该for版本将导致至少一些额外的Unapply实例和一些其他的东西.
所以简短的答案是肯定的,这取决于,如果你真的关心性能,你需要为你的特定用例做仔细的基准测试.
选择应用版本的最佳理由与性能没有任何关系,但它是您想要执行的计算的更精确表示.你a并且b不依赖于彼此,但for理解他们这样做.见我的答案在这里进行更多的讨论.
| 归档时间: |
|
| 查看次数: |
160 次 |
| 最近记录: |