Esk*_*ola 118 performance scala bytecode pattern-matching
如何在字节码级别实现Scala中的模式匹配?
它是否像一系列if (x instanceof Foo)结构或其他东西?它的性能影响是什么?
例如,给定以下代码(来自Scala By Example第46-48页),该方法的等效Java代码如何eval?
abstract class Expr
case class Number(n: Int) extends Expr
case class Sum(e1: Expr, e2: Expr) extends Expr
def eval(e: Expr): Int = e match {
case Number(x) => x
case Sum(l, r) => eval(l) + eval(r)
}
Run Code Online (Sandbox Code Playgroud)
PS我可以读取Java字节码,因此字节码表示对我来说已经足够了,但是对于其他读者来说,知道它看起来像Java代码会更好.
PPS Scala编程是否能够解答这一问题以及有关Scala如何实现的类似问题?我订购了这本书,但尚未到货.
Jam*_*Iry 93
可以用反汇编程序探索低级别,但简短的回答是它是一堆if/elses,谓词依赖于模式
case Sum(l,r) // instance of check followed by fetching the two arguments and assigning to two variables l and r but see below about custom extractors
case "hello" // equality check
case _ : Foo // instance of check
case x => // assignment to a fresh variable
case _ => // do nothing, this is the tail else on the if/else
Run Code Online (Sandbox Code Playgroud)
您可以使用"case Foo(45,x)"这样的模式或模式和组合做更多的事情,但通常这些只是我刚刚描述的逻辑扩展.模式也可以有守卫,这是对谓词的附加约束.在某些情况下,编译器可以优化模式匹配,例如,当案例之间存在一些重叠时,它可能会稍微合并一些事情.高级模式和优化是编译器中活跃的工作领域,因此如果字节代码在当前和未来版本的Scala中大大超过这些基本规则,请不要感到惊讶.
除此之外,除了Scala用于案例类的默认提取器之外,您还可以编写自己的自定义提取器.如果这样做,那么模式匹配的成本就是提取器所做的任何成本.http://lamp.epfl.ch/~emir/written/MatchingObjectsWithPatterns-TR.pdf中有一个很好的概述.
Jor*_*tiz 75
詹姆斯(上图)说得最好.但是,如果你很好奇,那么查看反汇编的字节码总是一个很好的练习.您也可以scalac使用该-print选项进行调用,该选项将打印您的程序,并删除所有Scala特定的功能.它基本上是Scala服装中的Java.以下是scalac -print您提供的代码段的相关输出:
def eval(e: Expr): Int = {
<synthetic> val temp10: Expr = e;
if (temp10.$isInstanceOf[Number]())
temp10.$asInstanceOf[Number]().n()
else
if (temp10.$isInstanceOf[Sum]())
{
<synthetic> val temp13: Sum = temp10.$asInstanceOf[Sum]();
Main.this.eval(temp13.e1()).+(Main.this.eval(temp13.e2()))
}
else
throw new MatchError(temp10)
};
Run Code Online (Sandbox Code Playgroud)
om-*_*nom 32
从版本2.8开始,Scala就有了@switch注释.目标是确保将模式匹配编译为tableswitch或lookupswitch而不是一系列条件if语句.
| 归档时间: |
|
| 查看次数: |
12168 次 |
| 最近记录: |