Mei 25, 2023 Pemrograman Sistem

Interpretation, Translation and Compilation

THE INTERPRETER

Dalam ilmu komputer, sebuah interpreter biasanya berarti program komputer yang mengeksekusi, yaitu melakukan, instruksi yang ditulis dalam bahasa pemrograman. Sementara interpretasi dan kompilasi adalah dua cara utama di mana bahasa pemrograman diimplementasikan, ini bukan kategori yang sepenuhnya berbeda, salah satu alasannya adalah bahwa sebagian besar sistem interpretasi juga melakukan beberapa pekerjaan terjemahan, seperti halnya kompiler.

Interpreter mungkin merupakan program yang baik

  1. Mengeksekusi kode sumber secara langsung.
  2. Menerjemahkan kode sumber menjadi beberapa representasi perantara (kode) yang efisien dan segera menjalankannya.
  3. Secara eksplisit mengeksekusi kode prekompilasi tersimpan yang dibuat oleh kompiler yang merupakan bagian dari sistem interpreter (juru bahasa).

Perl, Python, MATLAB, dan Ruby adalah contoh tipe 2, sedangkan UCSD, Pascal, dan Java adalah tipe 3: Program sumber dikompilasi sebelumnya dan disimpan sebagai kode independen mesin, yang kemudian ditautkan saat run-time dan dieksekusi oleh juru bahasa dan/atau kompiler (untuk sistem JIT). Beberapa sistem, seperti Smalltalk, dan lainnya, juga dapat menggabungkan 2 dan 3.

Istilah bahasa yang ditafsirkan atau bahasa yang dikompilasi hanya berarti bahwa implementasi kanonik dari bahasa itu adalah seorang interpreter (juru bahasa) atau compiler (penyusun); bahasa tingkat tinggi pada dasarnya adalah abstraksi yang (idealnya) tidak bergantung pada implementasi tertentu.

EFISIENSI, KEUNTUNGAN DAN KEKURANGAN

Kerugian utama dari interpreter adalah ketika sebuah program diinterpretasikan, biasanya berjalan lebih lambat daripada jika telah dikompilasi. Perbedaan kecepatan bisa kecil atau besar; sering urutan besarnya dan kadang-kadang lebih. Biasanya membutuhkan waktu lebih lama untuk menjalankan program di bawah juru bahasa daripada menjalankan kode yang dikompilasi tetapi membutuhkan waktu lebih sedikit untuk menafsirkannya daripada total waktu yang diperlukan untuk mengompilasi dan menjalankannya. Hal ini sangat penting saat membuat prototipe dan menguji kode ketika siklus edit-interpretasi-debug seringkali jauh lebih pendek daripada siklus edit-kompilasi-jalankan-debug.

Menafsirkan kode lebih lambat daripada menjalankan kode yang dikompilasi karena interpreter harus menganalisis setiap pernyataan dalam program setiap kali dieksekusi dan kemudian melakukan tindakan yang diinginkan, sedangkan kode yang dikompilasi hanya melakukan tindakan dalam konteks tetap yang ditentukan oleh kompilasi. Analisis run-time ini dikenal sebagai “overhead interpretatif”. Akses ke variabel juga lebih lambat dalam interpreter karena pemetaan pengidentifikasi ke lokasi penyimpanan harus dilakukan berulang kali pada waktu proses daripada pada waktu kompilasi.

Ada berbagai kompromi antara kecepatan pengembangan saat menggunakan interpreter dan kecepatan eksekusi saat menggunakan kompiler. Beberapa sistem (misalnya, beberapa LISP) memungkinkan kode yang diinterpretasikan dan dikompilasi untuk memanggil satu sama lain dan untuk berbagi variabel. Ini berarti bahwa setelah rutin diuji dan di-debug di bawah interpreter, itu dapat dikompilasi dan dengan demikian mendapat manfaat dari eksekusi yang lebih cepat sementara rutinitas lain sedang dikembangkan. Banyak interpreter tidak mengeksekusi kode sumber sebagaimana adanya tetapi mengubahnya menjadi bentuk internal yang lebih ringkas. Misalnya, beberapa interpreter BASIC mengganti kata kunci dengan token byte tunggal yang dapat digunakan untuk menemukan instruksi dalam tabel lompat. Sebuah interpreter mungkin menggunakan penganalisa dan pengurai leksikal yang sama dengan kompiler dan kemudian menginterpretasikan pohon sintaksis abstrak yang dihasilkan.

BYTECODE INTERPRETERS

Ada spektrum kemungkinan antara interpretasi dan kompilasi, bergantung pada jumlah analisis yang dilakukan sebelum program dijalankan. Misalnya, Emacs Lisp dikompilasi menjadi kode byte, yang merupakan representasi sumber Lisp yang sangat terkompresi dan dioptimalkan, tetapi bukan kode mesin (dan karenanya tidak terikat pada perangkat keras tertentu). Kode “dikompilasi” ini kemudian ditafsirkan oleh juru kode byte (ditulis sendiri dalam C). Kode yang dikompilasi dalam hal ini adalah kode mesin untuk mesin virtual, yang diimplementasikan bukan pada perangkat keras, tetapi pada interpreter kode byte. Pendekatan yang sama digunakan dengan kode Forth yang digunakan dalam sistem Open Firmware: bahasa sumber dikompilasi menjadi “kode F” (kode byte), yang kemudian diinterpretasikan oleh mesin virtual.

THE COMPILER

Kompiler adalah program komputer (atau serangkaian program) yang menerjemahkan teks yang ditulis dalam bahasa komputer (bahasa sumber) ke dalam bahasa komputer lain (bahasa target). Urutan asli biasanya disebut kode sumber dan keluarannya disebut kode objek. Umumnya output memiliki bentuk yang cocok untuk diproses oleh program lain (misalnya, linker), tetapi mungkin berupa file teks yang dapat dibaca manusia.

Alasan paling umum untuk menerjemahkan kode sumber adalah membuat program yang dapat dijalankan. Nama “kompiler” terutama digunakan untuk program yang menerjemahkan kode sumber dari bahasa pemrograman tingkat tinggi ke bahasa tingkat yang lebih rendah (misalnya, bahasa rakitan atau bahasa mesin). Program yang menerjemahkan dari bahasa tingkat rendah ke tingkat yang lebih tinggi adalah dekompilasi. Sebuah program yang menerjemahkan antar bahasa tingkat tinggi biasanya disebut sebagai language translator, source to source translator, atau language conventer. language rewriter biasanya merupakan program yang mengubah bentuk ekspresi tanpa mengubah bahasa.

Kompiler cenderung melakukan banyak atau semua operasi berikut: lexical analysis, preprocessing, parsing, semantic analysis, code generation, dan code optimization.

COMPILER OUTPUT

Salah satu klasifikasi kompiler adalah berdasarkan platform tempat kode yang dihasilkan dijalankan. Ini dikenal sebagai platform target.

Kompiler asli (native compiler) atau hosted compiler adalah yang keluarannya dimaksudkan untuk dijalankan secara langsung pada jenis komputer dan sistem operasi yang sama dengan yang dijalankan oleh kompiler itu sendiri. Output dari cross compiler dirancang untuk berjalan pada platform yang berbeda. Kompiler silang sering digunakan saat mengembangkan perangkat lunak untuk sistem tertanam yang tidak dimaksudkan untuk mendukung lingkungan pengembangan perangkat lunak.

Keluaran kompiler yang menghasilkan kode untuk mesin virtual (VM) mungkin atau mungkin tidak dieksekusi pada platform yang sama dengan kompiler yang memproduksinya. Untuk alasan ini, kompiler semacam itu biasanya tidak diklasifikasikan sebagai kompiler asli atau silang.

COMPILED VERSUS INTERPRETED LANGUAGES

Bahasa pemrograman tingkat tinggi umumnya dibagi untuk kenyamanan menjadi compiled languages dan interpreted languages. Namun, jarang ada bahasa yang mengharuskannya untuk dikompilasi secara eksklusif, atau diinterpreted secara eksklusif. Kategorisasi biasanya mencerminkan implementasi bahasa yang paling populer atau tersebar luas – misalnya, BASIC kadang-kadang disebut interpreted language, dan C adalah compiller language, meskipun ada kompiler BASIC dan interpreter C.

Dalam arti tertentu, semua bahasa diinterprestasikan, dengan “eksekusi” hanyalah kasus interpretasi khusus yang dilakukan oleh transistor yang menyalakan CPU. Tren modern menuju kompilasi just-in-time dan interpretasi kode byte juga mengaburkan kategorisasi tradisional.

Ada pengecualian. Beberapa spesifikasi bahasa menyatakan bahwa implementasi harus menyertakan fasilitas kompilasi; misalnya, Common Lisp. Bahasa lain memiliki fitur yang sangat mudah diimplementasikan dalam interpreter, tetapi membuat penulisan kompiler jauh lebih sulit; misalnya, APL, SNOBOL4, dan banyak bahasa scripting memungkinkan program untuk membuat kode sumber arbitrer saat runtime dengan operasi string reguler, lalu mengeksekusi kode tersebut dengan meneruskannya ke fungsi evaluasi khusus. Untuk mengimplementasikan fitur ini dalam bahasa yang dikompilasi, program biasanya harus dikirimkan dengan runtime library yang menyertakan versi kompiler itu sendiri.

ONE-PASS VERSUS MULTI-PASS COMPILERS

Mengklasifikasikan kompiler berdasarkan jumlah pass memiliki latar belakang keterbatasan sumber daya perangkat keras komputer. Kompilasi melibatkan banyak pekerjaan dan komputer awal tidak memiliki cukup memori untuk memuat satu program yang melakukan semua pekerjaan ini. Jadi kompiler dipecah menjadi program yang lebih kecil yang masing-masing melewati sumber (atau representasinya) melakukan beberapa analisis dan terjemahan yang diperlukan.

Kemampuan untuk mengkompilasi dalam satu pass sering dilihat sebagai keuntungan karena menyederhanakan pekerjaan menulis kompiler dan kompiler satu pass umumnya lebih cepat daripada kompiler multi-pass. Banyak bahasa dirancang sedemikian rupa sehingga dapat dikompilasi dalam single-pass (mis., Pascal).

Dalam beberapa kasus, desain fitur bahasa mungkin memerlukan kompiler untuk melakukan lebih dari satu pass sumber. Misalnya, pertimbangkan deklarasi yang muncul pada baris 20 dari sumber yang memengaruhi terjemahan pernyataan yang muncul pada baris 10. Dalam hal ini, pass pertama perlu mengumpulkan informasi tentang deklarasi yang muncul setelah pernyataan yang terpengaruh, dengan terjemahan yang sebenarnya terjadi selama pass berikutnya.

Kerugian dari kompilasi dalam single-pass adalah tidak mungkin melakukan banyak pengoptimalan canggih yang diperlukan untuk menghasilkan kode berkualitas tinggi. Mungkin sulit untuk menghitung dengan tepat berapa banyak lintasan yang dibuat oleh kompiler yang mengoptimalkan. Misalnya, fase pengoptimalan yang berbeda dapat menganalisis satu ekspresi berkali-kali tetapi hanya menganalisis ekspresi lain satu kali.

Memisahkan kompiler menjadi program-program kecil adalah teknik yang digunakan oleh para peneliti yang tertarik untuk menghasilkan kompiler yang terbukti benar. Membuktikan kebenaran dari sekumpulan program kecil seringkali membutuhkan usaha yang lebih sedikit daripada membuktikan kebenaran dari program yang lebih besar, tunggal, dan setara.

Sementara kompiler multi-pass yang khas mengeluarkan kode mesin dari pass terakhirnya, ada beberapa jenis lainnya:

  • Sebuah “source-to-source compiler” adalah jenis kompiler yang mengambil bahasa tingkat tinggi sebagai masukan dan mengeluarkan bahasa tingkat tinggi. Misalnya, kompiler paralelisasi otomatis akan sering mengambil program bahasa tingkat tinggi sebagai input dan kemudian mengubah kode dan membubuhi keterangan dengan anotasi kode paralel (misalnya OpenMP) atau konstruksi bahasa (misalnya pernyataan DOALL Fortran).
  • Stage compiler yang mengkompilasi ke bahasa rakitan mesin teoretis, seperti beberapa implementasi Prolog.
    Mesin Prolog ini juga dikenal sebagai Warren Abstract Machine (atau WAM). Kompiler kode byte untuk Java, Python, dan banyak lagi juga merupakan subtipe dari ini.
  • Kompiler just-in-time, digunakan oleh sistem Smalltalk dan Java, dan juga oleh Common Intermediate Language (CIL) Microsoft .Net

JUST-IN-TIME COMPILATION

Lebih lanjut mengaburkan perbedaan antara interpreters, interpreters dan kompilasi byte-kode adalah kompilasi just-in-time (atau JIT), sebuah teknik di mana representasi perantara dikompilasi ke kode mesin asli saat runtime. Hal ini memberikan efisiensi dalam menjalankan kode asli (native code), dengan mengorbankan waktu startup dan peningkatan penggunaan memori saat kode byte atau AST pertama kali dikompilasi. Optimalisasi adaptif (adaptive optimization) adalah teknik pelengkap di mana interpreter membuat profil program yang sedang berjalan dan mengkompilasi bagian-bagiannya yang paling sering dieksekusi ke dalam kode asli. Kedua teknik tersebut berusia beberapa dekade, muncul dalam bahasa seperti Smalltalk pada 1980-an.

Kompilasi just-in-time telah mendapatkan perhatian utama di antara para pelaksana bahasa dalam beberapa tahun terakhir, dengan Java, Python, dan .NET Framework semuanya sekarang termasuk JIT.

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *