Bagaimana pencocokan pola di Scala diimplementasikan pada tingkat bytecode?
Apakah itu seperti rangkaian if (x instanceof Foo)
konstruksi, atau sesuatu yang lain? Apa implikasi kinerjanya?
Misalnya, dengan kode berikut (dari Scala By Example halaman 46-48), bagaimana kode Java yang setara untuk eval
metode tersebut akan terlihat?
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)
}
PS Saya dapat membaca bytecode Java, jadi representasi bytecode akan cukup baik untuk saya, tetapi mungkin akan lebih baik bagi pembaca lain untuk mengetahui bagaimana tampilannya sebagai kode Java.
PPS Apakah buku Programming in Scala memberikan jawaban atas pertanyaan ini dan pertanyaan serupa tentang bagaimana Scala diterapkan? Saya sudah pesan bukunya, tapi belum sampai.
performance
scala
pattern-matching
bytecode
Esko Luontola
sumber
sumber
Jawaban:
Level rendah dapat dieksplorasi dengan disassembler tetapi jawaban singkatnya adalah bahwa itu adalah sekelompok if / elses di mana predikatnya tergantung pada polanya
Masih banyak lagi yang dapat Anda lakukan dengan pola atau pola dan kombinasi seperti "case Foo (45, x)", tetapi umumnya itu hanya ekstensi logis dari apa yang baru saja saya jelaskan. Pola juga dapat memiliki penjaga, yang merupakan batasan tambahan pada predikat. Ada juga kasus di mana kompilator dapat mengoptimalkan pencocokan pola, misalnya ketika ada beberapa tumpang tindih antar kasus, kompilator mungkin akan sedikit menyatu. Pola dan pengoptimalan lanjutan adalah area kerja aktif dalam kompiler, jadi jangan heran jika kode byte meningkat secara substansial melebihi aturan dasar ini dalam versi Scala saat ini dan yang akan datang.
Selain semua itu, Anda dapat menulis ekstraktor kustom Anda sendiri sebagai tambahan atau sebagai pengganti ekstraktor default yang digunakan Scala untuk kelas kasus. Jika Anda melakukannya, maka biaya pencocokan pola adalah biaya apa pun yang dilakukan ekstraktor. Tinjauan yang bagus dapat ditemukan di http://lamp.epfl.ch/~emir/written/MatchingObjectsWithPatterns-TR.pdf
sumber
James (di atas) mengatakan yang terbaik. Namun, jika Anda penasaran, selalu merupakan latihan yang baik untuk melihat bytecode yang dibongkar. Anda juga dapat memanggil
scalac
dengan-print
opsi, yang akan mencetak program Anda dengan semua fitur khusus Scala dihapus. Ini pada dasarnya Java dalam pakaian Scala. Berikut adalah hasil yang relevanscalac -print
untuk potongan kode yang Anda berikan:sumber
Sejak versi 2.8, Scala memiliki anotasi @switch . Tujuannya adalah untuk memastikan, bahwa pencocokan pola akan dikompilasi menjadi tableswitch atau lookupswitch alih-alih serangkaian
if
pernyataan bersyarat .sumber
@switch
lebih efisien daripada pencocokan pola biasa. jadi jika semua kasus berisi nilai konstan, Anda harus selalu menggunakan@switch
(karena implementasi bytecode akan sama dengan java,switch
bukan banyak if-else)