【问题标题】:Pattern matching overhead?模式匹配开销?
【发布时间】:2017-12-17 21:59:05
【问题描述】:

我是 Scala 和 Spark 的新手,我正在研究一种算法的实现。我想知道使用 scala 模式匹配是否方便以提高代码可读性,或者它是否实际上在执行期间引入了显着开销。我经常必须在地图函数中管理复杂的对象/嵌套元组,所以我问你通常的方法是什么。通常在我的比赛中没有真正的比较,它就像

COLLECTION.map{ case (A, (_,(C,_))) => do something with A and C) }

而不是

COLLECTION.map(pair => do something with pair._1 and pair._2._2._1)

非常感谢。

【问题讨论】:

  • 要测试算法的性能,你只需将时间测量放在算法执行周围......或者让不同算法的基准在它们周围使用相同的脚手架,这样开销时间,无论多高,都是恒定的。或者,只需使用相同的算法编写两个变体,测量执行时间,然后自己决定哪个更好。
  • @Dima 我的问题不同,与一般算法测试无关,而是与特定的scala模式匹配有关。考虑到最后一句话让您感到困惑,我将其从问题中删除。
  • 在这种情况下,答案是,没有明显的区别。这是一个品味问题。

标签: scala apache-spark pattern-matching


【解决方案1】:

编译器在您的第一个代码示例中为模式匹配调用的unapply 函数可能比第二个示例更昂贵,第二个示例不需要对值或类型进行自省或运行时测试。但是,第二个示例将失败,除非集合中的所有元素都是预期的类型,并且您没有向编译器指示预期的类型。

第一个示例中的模式匹配是否会产生大量开销取决于调用它的频率,相对于程序其余部分的计算。

【讨论】:

  • unapply 不需要自省。如果元素类型错误,两种方式都会失败。
  • 可以对类型和/或值进行匹配。如果 unapply 被调用,那么它是有代价的。有很多方法可以匹配。按类型匹配使用自省
  • 此模式中没有unapply
  • @Martijn case (A, (_,(C,_))) 实际上是对unapply 的调用。它的“成本”是创建和销毁堆栈帧,这对于所有实际目的都是“免费的”。
  • @MikeSlinn 自从(我认为)java 4 左右以来,找出变量的类型并不是一项昂贵的操作......此外,如果您需要知道类型,您将不管是模式匹配还是没有模式匹配,都必须付出这个代价。而且,再一次,第一个示例中没有自省。
【解决方案2】:

匹配的开销很小。元组匹配将参数直接提升为元组,unapply 不处理元组模式。

中的f
class Foo {
  val f: ((Double, Int)) => Double = { case (d, i) => d + i }
}

被编译(没有优化标志)到

     0: aload_0
     1: astore_3
     2: aload_3
     3: ifnull        21
     6: aload_3
     7: invokevirtual #35                 // Method scala/Tuple2._2$mcD$sp:()D
    10: dstore        4
    12: dload         4
    14: iconst_1
    15: i2d
    16: dadd
    17: dstore_1
    18: goto          33
    21: goto          24
    24: new           #37                 // class scala/MatchError
    27: dup
    28: aload_3
    29: invokespecial #41                 // Method scala/MatchError."<init>":(Ljava/lang/Object;)V
    32: athrow
    33: dload_1
    34: dreturn

那里有一个匹配错误的(没有结果的)测试。

您认为可以接受多少开销通常无法真正回答。

【讨论】:

    猜你喜欢
    • 2010-09-17
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多