1. ホーム
  2. performance

[解決済み] Scalaのパターンマッチはバイトコードレベルでどのように実装されているのですか?

2022-07-18 23:26:39

質問

Scalaのパターンマッチは、バイトコードレベルでどのように実装されていますか?

それは、一連の if (x instanceof Foo) のようなものなのでしょうか?そのパフォーマンスにはどのような意味があるのでしょうか?

例えば、次のようなコード( Scalaの例 ページ46-48) がある場合,同等のJavaコードで eval メソッドに相当するJavaのコードはどのように見えるでしょうか?

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)
}

追伸:私はJavaバイトコードを読むことができるので、バイトコード表現で十分ですが、おそらく他の読者にとっては、それがJavaコードとしてどのように見えるかを知る方がよいのでしょう。

P.P.S. 本は Scalaでプログラミング は、Scala がどのように実装されているかについてのこれと同様の質問に対する答えを与えてくれますか?私は本を注文しましたが、まだ到着していません。

どのように解決するのですか?

低レベルなものはディスアセンブラで調べることができますが、簡単に言うと、述語がパターンに依存するif/elesの束になります。

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

パターンを使ってできることは他にもたくさんあります。例えば、パターンや組み合わせは "case Foo(45, x)" のようになりますが、一般的には今説明したことを論理的に拡張しただけのことです。 パターンにはガードという述語に対する追加の制約を持たせることもできる。 また、コンパイラがパターン・マッチングを最適化する場合もある。例えば、ケース間に重複がある場合、少しまとめることができる。 高度なパターンと最適化はコンパイラの活発な作業領域なので、現在と将来のバージョンのScalaでバイトコードがこれらの基本ルールより大幅に改善されても驚かないでください。

これらのことに加えて、Scalaがケースクラスに対して使うデフォルトのものに加えて、あるいは代わりに、独自のカスタム抽出器を書くことができます。 その場合、パターンマッチのコストは、抽出器が何をするにしても、そのコストになります。 良い概要が http://lamp.epfl.ch/~emir/written/MatchingObjectsWithPatterns-TR.pdf にある。