Misalkan sebuah program ditulis dalam dua bahasa yang berbeda, biarkan mereka menjadi bahasa X dan bahasa Y, jika kompiler mereka menghasilkan kode byte yang sama, mengapa saya harus menggunakan bahasa X alih-alih bahasa Y? Apa yang mendefinisikan bahwa satu bahasa lebih cepat dari yang lain?
Saya bertanya ini karena sering Anda melihat orang mengatakan hal-hal seperti: "C adalah bahasa tercepat, ATS adalah bahasa secepat C". Saya sedang berusaha memahami definisi "cepat" untuk bahasa pemrograman.
programming-languages
compilers
Rodrigo Valente
sumber
sumber
Jawaban:
Ada banyak alasan yang dapat dipertimbangkan untuk memilih bahasa X daripada bahasa Y. Keterbacaan program, kemudahan pemrograman, portabilitas ke banyak platform, keberadaan lingkungan pemrograman yang baik dapat menjadi alasan tersebut. Namun, saya hanya akan mempertimbangkan kecepatan eksekusi seperti yang diminta dalam pertanyaan. Pertanyaannya tampaknya tidak mempertimbangkan, misalnya, kecepatan perkembangan.
Dua bahasa dapat dikompilasi dengan bytecode yang sama, tetapi itu tidak berarti bahwa kode yang sama akan diproduksi,
Sebenarnya bytecode hanya kode untuk mesin virtual tertentu. Itu memang memiliki keunggulan teknik, tetapi tidak memperkenalkan perbedaan mendasar dengan mengkompilasi secara langsung untuk harware tertentu. Jadi, Anda sebaiknya mempertimbangkan membandingkan dua bahasa yang dikompilasi untuk eksekusi langsung pada mesin yang sama.
Ini mengatakan, masalah kecepatan relatif dari bahasa adalah yang lama, dating kembali ke kompiler pertama.
Selama bertahun-tahun, pada masa-masa awal itu, profesional menganggap bahwa kode tulisan tangan lebih cepat daripada kode yang dikompilasi. Dengan kata lain, bahasa mesin dianggap lebih cepat daripada bahasa tingkat tinggi seperti Cobol atau Fortran. Dan itu, lebih cepat dan biasanya lebih kecil. Bahasa tingkat tinggi masih berkembang karena lebih mudah digunakan untuk banyak orang yang bukan ilmuwan komputer. Biaya menggunakan bahasa tingkat tinggi bahkan memiliki nama: rasio ekspansi, yang dapat menyangkut ukuran kode yang dihasilkan (masalah yang sangat penting pada masa itu) atau jumlah instruksi yang benar-benar dieksekusi. Konsep ini terutama eksperimental, tetapi rasionya lebih besar dari 1 pada awalnya, karena kompiler melakukan pekerjaan yang berpikiran sederhana menurut standar saat ini.
Dengan demikian bahasa mesin lebih cepat daripada mengatakan, Fortran.
Tentu saja, itu berubah selama bertahun-tahun, ketika kompiler menjadi lebih canggih, ke titik bahwa pemrograman dalam bahasa assembly sekarang sangat jarang. Untuk sebagian besar aplikasi, program bahasa assembly tidak mampu bersaing dengan kode yang dihasilkan dengan mengoptimalkan kompiler.
Ini menunjukkan bahwa satu masalah utama adalah kualitas kompiler yang tersedia untuk bahasa yang dipertimbangkan, kemampuan mereka untuk menganalisis kode sumber, dan untuk mengoptimalkannya.
Kemampuan ini mungkin bergantung pada beberapa perluasan fitur bahasa untuk menekankan sifat struktural dan matematika dari sumber untuk membuat pekerjaan lebih mudah bagi kompiler. Sebagai contoh, sebuah bahasa dapat memungkinkan penyertaan pernyataan tentang properti aljabar fungsi yang ditentukan pengguna, sehingga memungkinkan kompiler untuk menggunakan properti ini untuk tujuan optimasi.
Proses kompilasi mungkin lebih mudah, maka menghasilkan kode yang lebih baik, ketika paradigma pemrograman bahasa lebih dekat dengan fitur mesin yang akan mengintepret kode, apakah mesin nyata atau virtual.
Poin lainnya adalah apakah paradigma yang diterapkan dalam bahasa tertutup dengan jenis masalah yang diprogram. Diharapkan bahwa bahasa pemrograman yang dikhususkan untuk paradigma pemrograman tertentu akan mengkompilasi fitur yang sangat efisien terkait dengan paradigma itu. Oleh karena itu pilihan bahasa pemrograman dapat bergantung, untuk kejelasan dan kecepatan, pilihan bahasa pemrograman yang disesuaikan dengan jenis masalah yang diprogram.
Popularitas C untuk pemrograman sistem mungkin karena fakta bahwa C dekat dengan arsitektur mesin, dan pemrograman sistem secara langsung terkait dengan arsitektur itu juga.
Beberapa masalah lain akan lebih mudah diprogram, dengan eksekusi lebih cepat menggunakan pemrograman logika dan bahasa resolusi kendala .
Sistem reaktif yang kompleks dapat diprogram dengan sangat efisien dengan bahasa pemrograman sinkron khusus seperti Esterel yang mewujudkan pengetahuan yang sangat khusus tentang sistem tersebut dan menghasilkan kode yang sangat cepat.
Atau untuk mengambil contoh ekstrem, beberapa bahasa sangat khusus, seperti bahasa deskripsi sintaksis yang digunakan untuk memprogram parser. Sebuah parser generator tidak lain adalah sebuah compiler untuk bahasa tersebut. Tentu saja, ini bukan Turing lengkap, tetapi kompiler ini sangat bagus untuk spesialisasi mereka: menghasilkan program parsing yang efisien. Domain pengetahuan dibatasi, teknik pengoptimalan bisa sangat khusus dan disetel dengan sangat halus. Generator parser ini biasanya jauh lebih baik daripada yang bisa diperoleh dengan menulis kode dalam bahasa lain. Ada banyak bahasa yang sangat terspesialisasi dengan kompiler yang menghasilkan kode yang sangat baik dan cepat untuk kelas masalah yang terbatas.
Oleh karena itu, ketika menulis sistem yang besar, mungkin disarankan untuk tidak bergantung pada satu bahasa, tetapi untuk memilih bahasa terbaik untuk berbagai komponen sistem. Ini, tentu saja, menimbulkan masalah kompatibilitas.
Poin lain yang sering penting adalah keberadaan perpustakaan yang efisien untuk topik yang diprogram.
Akhirnya, kecepatan bukan satu-satunya kriteria dan mungkin bertentangan dengan kriteria lain seperti keamanan kode (untuk contoh sehubungan dengan input yang buruk, atau ketahanan terhadap kesalahan sistem), penggunaan memori, kemudahan pemrograman (meskipun kompatibilitas paradigma sebenarnya dapat membantu ), ukuran kode objek, kemampuan pemeliharaan program, dll.
Kecepatan tidak selalu merupakan parameter yang paling penting. Juga mungkin diperlukan kedok yang berbeda, seperti kompleksitas yang mungkin kompleksitas rata-rata atau kompleksitas kasus yang lebih buruk. Juga, dalam sistem besar seperti dalam program yang lebih kecil, ada bagian-bagian di mana kecepatan sangat penting, dan yang lain tidak penting. Dan tidak selalu mudah untuk menentukannya terlebih dahulu.
sumber
Sementara semuanya pada akhirnya berjalan di CPU * , ada berbagai perbedaan antara bahasa yang berbeda. Berikut ini beberapa contohnya.
Bahasa ditafsirkan Beberapa bahasa yang ditafsirkan bukan dikompilasi , misalnya Python, Ruby dan Matlab. Itu berarti bahwa kode Python dan Ruby tidak dikompilasi ke kode mesin, melainkan ditafsirkan secara langsung. Dimungkinkan untuk mengkompilasi Python dan Ruby ke mesin virtual (lihat poin berikutnya). Lihat juga pertanyaan ini . Ditafsirkan pada umumnya lebih lambat dari kode yang dikompilasi karena berbagai alasan. Tidak hanya penafsiran itu sendiri lambat, juga lebih sulit untuk melakukan optimasi. Namun, jika kode Anda menghabiskan sebagian besar waktu pada fungsi perpustakaan (kasus Matlab), kinerja tidak akan berkurang.
Mesin virtual Beberapa bahasa dikompilasi menjadi bytecode , "kode mesin" yang ditemukan yang kemudian ditafsirkan. Contoh klasik adalah Java dan C #. Sementara bytecode dapat dikonversi ke kode mesin dengan cepat, kode tersebut mungkin masih berjalan lebih lambat. Dalam kasus Java, mesin virtual digunakan untuk portabilitas. Dalam kasus C #, mungkin ada masalah lain seperti keamanan.
Overhead Beberapa bahasa memperdagangkan efisiensi untuk keamanan. Misalnya, beberapa versi Pascal akan memeriksa apakah Anda tidak mengakses array di luar batas. Kode C # "dikelola", dan ini berbayar. Contoh umum lainnya adalah pengumpulan sampah, yang menghemat waktu untuk programmer tetapi tidak seefisien manajemen memori. Ada sumber overhead lain seperti infrastruktur untuk penanganan pengecualian atau untuk mendukung pemrograman berorientasi objek.
* Faktanya, saat ini sistem dengan kinerja tinggi juga menjalankan kode pada GPU dan bahkan pada FPGA.
sumber
Ada beberapa faktor untuk memilih X dan bukan Y, seperti
Beberapa bahasa cocok untuk mengembangkan proyek bisnis seperti C # atau Python, tetapi di sisi lain beberapa di antaranya bagus untuk pemrograman sistem seperti C ++.
Anda harus menentukan di bawah platform apa Anda akan bekerja dan aplikasi apa yang akan Anda buat.
sumber
Bahasa pemrograman "tercepat" yang bisa Anda peroleh dengan platform apa pun adalah bahasa rakitan untuk chipset yang Anda hadapi. Pada level itu tidak ada terjemahan. Namun perlu ada beberapa pengetahuan tentang bagaimana chipset mengeksekusi instruksi terutama yang dapat melakukan hal-hal secara paralel.
Konversi dari C ke perakitan sangat "dangkal" sehingga mendekati satu tetapi satu lebih mudah dibaca. Namun ia memiliki banyak lapisan di atasnya karena pustaka standar untuk meningkatkan portabilitas. Tidak ada banyak hal yang perlu dilakukan oleh kompiler untuk mendapatkan kode assembly dan optimisasi yang lebih kuat umumnya ada untuk membuat perubahan spesifik mesin.
C ++ menambahkan bahasa yang lebih kaya. Namun karena bahasa menambahkan begitu banyak kompleksitas, semakin sulit bagi kompiler untuk membuat kode optimal untuk platform.
Lalu kita pergi ke sisi lain dari skala. Bahasa yang ditafsirkan. Ini cenderung paling lambat karena selain melakukan pekerjaan ada beberapa waktu yang dihabiskan untuk mengurai kode dan mengubahnya menjadi panggilan mesin.
Lalu kita memiliki mereka di antaranya. Secara umum mereka memiliki lapisan mesin virtual yang dioptimalkan untuk platform. Dan kompiler akan membuat kode untuk dieksekusi oleh mesin virtual. Terkadang ini terjadi sekaligus seperti perl atau pascal atau ruby atau Python. Atau dalam beberapa tahap seperti java.
Beberapa mesin virtual ini menambahkan gagasan tentang kompiler JIT yang mempercepat runtime juga dengan membuat kode level mesin daripada menerjemahkan kode byte menengah.
Beberapa mesin virtual adalah level rendah yang memungkinkan lebih sedikit terjemahan dari kode byte ke kode mesin. Yang mempercepat sementara menjaga portabilitas.
sumber
*p++=*q++;
pada banyak mesin lebih cepat daripadaarray1[i]=array2[i];
tetapi pada banyak prosesor, kebalikannya sering benar dan dengan demikian kompiler dapat akhirnya mengubah gaya kode yang sebelumnya menjadi yang terakhir - bukan konversi yang "dangkal".-O0
tidak akan melakukan optimasi. Optimalisasi adalah bonus yang Anda peroleh dengan kompiler, tetapi bahasa itu sendiri dapat menerjemahkan dekat satu ke satu ke perakitan.Poin yang belum disebutkan adalah bahwa dalam beberapa bahasa, menjalankan kode yang sama berkali-kali akan selalu melakukan urutan tindakan yang sama; komputer hanya perlu menentukan sekali bagian kode apa yang harus dilakukan. Salah satu manfaat utama dari dialek JavaScript "ketat" adalah bahwa setelah mesin JavaScript mengetahui apa yang dilakukan oleh sepotong kode, ia dapat memanfaatkan informasi itu saat dijalankan berikutnya; tanpa "gunakan ketat", itu tidak bisa.
Misalnya, dengan tidak adanya "gunakan ketat", sepotong kode seperti:
dapat mengembalikan variabel X dalam konteks panggilan langsung, jika ada, atau variabel X dari konteks panggilan luar, atau mungkin kembali
Undefined
. Lebih buruk, dalam satu lingkaran seperti:tidak ada cara bagi mesin JavaScript untuk mengetahui apa yang
g()
mungkin dilakukan dengani
[atau untukg
dirinya sendiri dalam hal ini. Karenag
ataui
dapat secara sah berubahi
menjadi string, mesin JavaScript tidak bisa hanya menggunakan penambahan numerik dan perbandingan numerik dalam loop, tetapi harus pada setiap melewati pemeriksaan loop untuk melihat apakah salah satu dari panggilan fungsi telah melakukan sesuatu untuki
ataug
. Sebaliknya, dalam dialek "gunakan ketat" [agak waras], mesin JavaScipt dapat memeriksa kode di atas dan mengetahui bahwa setiap melewati loop akan menggunakan variabel numerik yang sama dan menjalankan fungsi yang sama. Dengan demikian hanya perlu mengidentifikasii
dan berfungsig
sekali, daripada harus mencari mereka di setiap melewati loop - penghematan waktu utama.sumber
Ada beberapa jawaban yang cukup profesional di sini, yang ini tidak dekat dengan mereka tetapi mungkin intuitif untuk Anda.
Anda mungkin telah mendengar berkali-kali bahwa ketika Anda perlu melakukan tugas secepat mungkin Anda ingin menulis kode yang mengeksekusinya dalam kumpulan. Itu karena Anda hanya menjalankan perintah yang sebenarnya Anda perlukan untuk menyelesaikan tugas dan tidak lebih. Sementara pada bahasa tingkat tinggi Anda bisa mengimplementasikan tugas ini dalam beberapa baris, kompiler masih perlu menerjemahkannya ke bahasa mesin. Terjemahan ini tidak selalu minimalis karena Anda dapat menulisnya secara langsung. Itu berarti bahwa mesin akan menghabiskan banyak jam untuk menjalankan perintah yang bisa Anda pakai.
Meskipun kompiler sangat canggih saat ini mereka masih tidak efektif karena programmer perakitan terbaik bisa.
Melanjutkan ke arah ini, perintah-perintah yang tidak dibutuhkan tumbuh dalam jumlah mereka (biasanya) karena bahasa diratakan lebih tinggi. (ini tidak 100% benar untuk semua bahasa tingkat tinggi)
Jadi bagi saya, bahasa X lebih cepat daripada bahasa Y (saat runtime) jika untuk bagian kode tertentu, kode mesin X lebih pendek daripada bahasa Y.
sumber
Sulit untuk menjawab pertanyaan ini secara definitif karena begitu kompleks dan multidimensi (hampir seperti misalnya membandingkan merek mobil dengan kriteria misc.) Tetapi ada studi ilmiah baru termasuk repositori kode yang sangat baik yang dikenal sebagai kode Rosetta , ( tinjauan wikipedia ). Survei tahun 2014 oleh Nanz dan Furia ini mempelajari pertanyaan ini secara cukup definitif dan ilmiah berdasarkan kriteria tipikal berikut dan analisis kuantitatif yang jarang dari kualitas kode subyektif yang khas. Abstrak berisi beberapa temuan dan generalisasi yang beralasan secara objektif. (Semoga penelitian lain yang membangun hasil ini dapat dilakukan di masa depan.)
RQ1. Bahasa pemrograman mana yang menghasilkan kode yang lebih ringkas?
RQ2. Bahasa pemrograman mana yang dikompilasi menjadi executable yang lebih kecil?
RQ3. Bahasa pemrograman mana yang memiliki kinerja running-time yang lebih baik?
RQ4. Bahasa pemrograman mana yang menggunakan memori lebih efisien?
RQ5. Bahasa pemrograman mana yang lebih rentan terhadap kegagalan?
sumber
Bahasa komputer hanyalah abstraksi dari perintah untuk menjelaskan pada komputer apa yang harus dilakukan.
Anda bahkan dapat menulis dalam bahasa komputer
Python
dan mengompilasinya dengan kompiler C (cython).Ingatlah ini, kecepatan bahasa komputer tidak dapat dibandingkan.
Tetapi Anda dapat membandingkan kompiler untuk bahasa yang sama hingga beberapa ekstensi. Misalnya
GNU C
kompiler versusIntel C
kompiler. (Cari patokan kompiler)sumber