Mengapa C sangat cepat, dan mengapa bahasa lain tidak secepat atau lebih cepat? [Tutup]

209

Dalam mendengarkan podcast StackOverflow, jab terus muncul sehingga "programmer nyata" menulis dalam C, dan bahwa C jauh lebih cepat karena "dekat dengan mesin." Meninggalkan pernyataan sebelumnya untuk pos lain, apa yang istimewa tentang C yang membuatnya lebih cepat daripada bahasa lain? Atau dengan kata lain: apa yang membuat bahasa lain tidak bisa dikompilasi menjadi biner yang berjalan setiap bit secepat C?

Mike C.
sumber
6
Bisakah Anda daftar acara mana yang dibicarakan? Saya ingin sekali mendengarnya.
Giovanni Galbo
2
Sangat terkejut melihat betapa buruknya pertanyaan ini dijawab (sebagian besar jawaban mengabaikan perbedaan mendasar antara bahasa yang dikompilasi dan ditafsirkan dll, saya tahu tentang JIT yada yada yada), dan berapa banyak orang yang mengambil posisi 'membela' bahasa favorit mereka (FORTRAN boy perlu untuk minum pil).
Tim Ring
Jangan lupa bahasa assembly. Tidak ada yang lebih cepat atau lebih kompak dari ongkos perakitan. Perakitan hampir murni biner sehingga tanpa bias bahasa tercepat.
KKZiomek
3
C adalah yang tercepat karena kecepatan cahaya, dan relativitas?
Temui Taraviya
Tentu saja salah bahwa C adalah bahasa program tercepat. Tidak ada bahasa program dalam bentuk apa pun yang mendekati kecepatan FORTH. FORTH digunakan untuk memicu bom nuklir, itu adalah bahasa program pada sebagian besar satelit, bahasa program utama di Stasiun Luar Angkasa Internasional dan juga di CERN dan di ITER. Saya membandingkan kecepatan antara Microsoft C (Versi berbeda) dan FORTH. YAWN to C ...
Scoobeedo Cool

Jawaban:

200

Tidak banyak yang spesial tentang C. Itu salah satu alasan mengapa itu cepat.

Bahasa yang lebih baru yang memiliki dukungan untuk pengumpulan sampah , pengetikan dinamis , dan fasilitas lainnya yang memudahkan programmer untuk menulis program.

Tangkapannya adalah, ada overhead pemrosesan tambahan yang akan menurunkan kinerja aplikasi. C tidak memiliki semua itu, yang berarti bahwa tidak ada overhead, tetapi itu berarti bahwa programmer harus dapat mengalokasikan memori dan membebaskan mereka untuk mencegah kebocoran memori , dan harus berurusan dengan pengetikan variabel statis.

Yang mengatakan, banyak bahasa dan platform, seperti Java (dengan Java Virtual Machine ) dan .NET (dengan Common Language Runtime) telah meningkatkan kinerja selama bertahun-tahun dengan kemajuan seperti kompilasi just-in-time yang menghasilkan kode mesin asli dari bytecode untuk mencapai kinerja yang lebih tinggi.

coobird
sumber
3
pengumpulan sampah bisa lebih cepat daripada manajemen memori manual (untuk program yang berumur pendek dan / atau banyak memori). GC memungkinkan alokasi yang sederhana dan cepat, dan program tidak menghabiskan waktu untuk melakukan hal-hal yang tidak perlu.
Kornel
2
Program C umumnya mengalokasikan dan mengalokasikan memori pada basis yang diperlukan. Ini tidak efisien. VM yang baik akan mengalokasikan dan mengalokasikan dalam potongan besar, menghasilkan keuntungan besar dalam kinerja dalam banyak kasus.
skaffman
61
Tidak ada yang mencegah program C dari melakukan alokasi chunked dan pengumpulan sampah yang sama, selain menjadi "sulit".
ephemient
Sangat baik dikatakan, tetapi seperti kata Rob Allen, C juga memberikan abstraksi lebih sedikit daripada Java atau .NET, menghasilkan terjemahan yang lebih sedikit (yang kurang benar hari ini karena kompilasi just-in-time (JIT) seperti yang Anda katakan)
Gab Royer
5
porneL, manajemen manual, dan alokasi yang masuk akal akan selalu mengungguli sistem GC mana pun ketika digunakan dengan benar dan banyak perhatian diberikan, Anda memiliki pengetahuan absolut tentang pola penggunaan Anda, GC tidak, ditambah sistem GC menambah overhead
Ion Todirel
89

Ada trade off yang telah dibuat oleh desainer C. Itu artinya, mereka membuat keputusan untuk menempatkan kecepatan di atas keselamatan. C tidak akan

  • Periksa batas indeks array
  • Periksa nilai variabel yang tidak diinisialisasi
  • Periksa kebocoran memori
  • Periksa dereferensi penunjuk nol

Ketika Anda mengindeks ke dalam array, di Jawa dibutuhkan beberapa panggilan metode di mesin virtual, memeriksa terikat dan cek kewarasan lainnya. Itu valid dan benar-benar baik-baik saja , karena menambah keamanan di mana itu karena. Tetapi dalam C, bahkan hal-hal sepele yang cantik tidak dimasukkan ke dalam keamanan. Sebagai contoh, C tidak memerlukan memcpy untuk memeriksa apakah wilayah untuk menyalin tumpang tindih. Ini tidak dirancang sebagai bahasa untuk memprogram aplikasi bisnis besar.

Tapi keputusan desain ini tidak bug dalam bahasa C . Mereka dirancang, karena memungkinkan kompiler dan penulis perpustakaan untuk mendapatkan setiap bit kinerja dari komputer. Inilah semangat C bagaimana dokumen C Rationale menjelaskannya:

Kode C bisa non-portabel. Meskipun berusaha untuk memberi para programmer kesempatan untuk menulis program yang benar-benar portabel, Komite tidak ingin memaksa programmer untuk menulis dengan mudah, untuk menghalangi penggunaan C sebagai `` assembler tingkat tinggi '': kemampuan untuk menulis khusus mesin kode adalah salah satu kekuatan C.

Jaga semangat C. Komite terus sebagai tujuan utama untuk melestarikan semangat tradisional C. Ada banyak sisi dari semangat C, tetapi esensinya adalah sentimen komunitas dari prinsip-prinsip yang mendasari di mana bahasa C didasarkan. Beberapa aspek dari semangat C dapat diringkas dalam frasa seperti

  • Percaya programmer.
  • Jangan mencegah programmer melakukan apa yang perlu dilakukan.
  • Jaga bahasa tetap kecil dan sederhana.
  • Berikan hanya satu cara untuk melakukan operasi.
  • Jadikan cepat, meskipun tidak dijamin portabel.

Pepatah terakhir membutuhkan sedikit penjelasan. Potensi untuk pembuatan kode yang efisien adalah salah satu kekuatan paling penting dari C. Untuk membantu memastikan bahwa tidak ada ledakan kode yang muncul untuk apa yang tampak sebagai operasi yang sangat sederhana, banyak operasi didefinisikan sebagai bagaimana perangkat keras mesin target melakukannya daripada oleh aturan abstrak umum. Contoh dari kesediaan untuk hidup dengan apa yang dilakukan mesin dapat dilihat dalam aturan yang mengatur pelebaran objek char untuk digunakan dalam ekspresi: apakah nilai objek char melebar ke jumlah yang ditandatangani atau tidak, biasanya tergantung pada operasi byte mana yang lebih efisien pada mesin target.

Johannes Schaub - litb
sumber
51
C tidak memeriksa deref pointer nol dengan menabrak keras :-). Itu juga kadang-kadang memeriksa indeks array out-of-range dan variabel tidak diinisialisasi dengan mengacaukan frame tumpukan Anda dan data. Sayangnya itu memeriksa ini saat runtime.
paxdiablo
18
Saya tidak akan mengatakan bahwa C tidak aman, yang terdengar seperti apa yang Anda isyaratkan. Diasumsikan Anda bukan idiot. Jika Anda mengarahkan pistol ke bawah dan menembak diri sendiri di kaki, C dengan senang hati akan menurut dan membiarkan Anda melakukan itu karena mengasumsikan Anda lebih pintar daripada itu. Itu belum tentu hal yang buruk.
Bob Somers
19
@ Bob: Tepat. Mengatakan C tidak aman karena memungkinkan Anda melakukan hal-hal berbahaya seperti mengatakan mobil tidak aman karena akan membiarkan Anda berkendara dari tebing. C seaman orang yang mengemudi (tetapi ada banyak pengemudi yang tidak aman di luar sana).
Robert Gamble
5
Bob, membuat bug seperti buffer overruns tidak berarti Anda idiot. Itu berarti Anda masih manusia. Saya menyadari bahwa C dan C ++ tidak buruk (saya sangat menyukainya).
Johannes Schaub - litb
4
@ JohannesSchaub-litb C sangat cocok untuk pemrograman aplikasi skala besar. Jika seseorang merasa sulit untuk membuat proyek lebih besar dari dunia halo, maka masalahnya adalah dengan programmer, bukan dengan bahasa ...
75

Jika Anda menghabiskan satu bulan untuk membangun sesuatu dalam C yang berjalan dalam 0,05 detik, dan saya menghabiskan sehari menulis hal yang sama di Jawa, dan itu berjalan dalam 0,10 detik, lalu apakah C benar-benar lebih cepat?

Tetapi untuk menjawab pertanyaan Anda, kode C yang ditulis dengan baik umumnya akan berjalan lebih cepat daripada kode yang ditulis dengan baik dalam bahasa lain karena bagian dari penulisan kode C "baik" termasuk melakukan optimasi manual pada tingkat yang dekat dengan mesin.

Meskipun kompiler memang sangat pintar, mereka belum dapat secara kreatif menghasilkan kode yang bersaing dengan algoritma pijatan tangan (dengan asumsi "tangan" milik programmer C yang baik ).

Edit:

Banyak komentar di sepanjang baris "Saya menulis dalam C dan saya tidak berpikir tentang optimasi."

Tetapi untuk mengambil contoh spesifik dari pos ini :

Dalam Delphi saya bisa menulis ini:

function RemoveAllAFromB(a, b: string): string;
var
  before, after :string;
begin
  Result := b;
  if 0 < Pos(a,b) then begin
    before := Copy(b,1,Pos(a,b)-Length(a));
    after := Copy(b,Pos(a,b)+Length(a),Length(b));
    Result := before + after;
    Result := RemoveAllAFromB(a,Result);  //recursive
  end;
end;

dan di CI tulis ini:

char *s1, *s2, *result; /* original strings and the result string */
int len1, len2; /* lengths of the strings */
for (i = 0; i < len1; i++) {
   for (j = 0; j < len2; j++) {
     if (s1[i] == s2[j]) {
       break;
     }
   }
   if (j == len2) {  /* s1[i] is not found in s2 */
     *result = s1[i]; 
     result++; /* assuming your result array is long enough */
   }
}

Tetapi berapa banyak optimasi yang ada dalam versi C? Kami membuat banyak keputusan tentang implementasi yang tidak saya pikirkan dalam versi Delphi. Bagaimana string diimplementasikan? Dalam Delphi saya tidak melihatnya. Dalam C, saya telah memutuskan itu akan menjadi pointer ke array bilangan bulat ASCII, yang kita sebut karakter. Di C, kami menguji keberadaan karakter satu per satu. Di Delphi, saya menggunakan Pos.

Dan ini hanyalah contoh kecil. Dalam sebuah program besar, seorang programmer C harus membuat keputusan tingkat rendah dengan setiap baris kode. Ini menambah hingga dapat dieksekusi, dioptimalkan dengan tangan.

JosephStyons
sumber
46
Agar adil, tidak banyak yang akan memakan waktu satu bulan di C yang akan memakan waktu hanya satu hari di Jawa yang hanya membutuhkan 0,05 detik untuk dieksekusi (yaitu program kecil).
dreamlax
13
Saya telah memprogram dalam C selama bertahun-tahun dan hampir tidak pernah harus melakukan salah satu dari jenis optimasi yang Anda mengisyaratkan. Saya telah mem-porting sejumlah program ke C (terutama dari Perl) dan umumnya melihat peningkatan kecepatan 10x plus dan pengurangan signifikan dalam penggunaan memori tanpa optimasi kode tangan.
Robert Gamble
1
Tentu saja ada beberapa hal yang bisa memakan waktu lebih lama untuk diprogram dalam C karena kurangnya fasilitas yang ada sehingga merupakan pertukaran antara kinerja komputer dan kinerja programmer (antara lain) yang mengapa kita tidak semua memprogram semuanya dalam C.
Robert Gamble
4
Saya telah membuat program C ++ yang memproses ribuan baris data dalam waktu yang lebih singkat daripada program Java atau .NET yang dapat dimulai. Ini adalah salah satu frustrasi yang saya miliki dengan bahasa yang lebih modern. C sangat bagus untuk program lean yang membutuhkan persyaratan runtime minimal. PowerBasic juga bagus untuk itu.
bruceatk
35
Anda mengatakan program yang membutuhkan waktu sebulan di C dan dua kali lebih cepat dari program yang ditulis di Jawa yang hanya membutuhkan waktu satu hari untuk menulis tidak berharga? Bagaimana jika program itu perlu dijalankan 500.000.000+ kali sehari? Menjadi dua kali lebih cepat sangat signifikan. Jika beroperasi pada ribuan atau jutaan CPU, penghematan biaya pengembangan ekstra bulan untuk mencapai dua kali kinerja akan sangat besar. Pada dasarnya, Anda harus mengetahui / memahami skala penyebaran Anda sebelum memilih platform pengembangan.
nicerobot
49

Aku tidak melihatnya sudah, jadi saya akan mengatakannya: C cenderung lebih cepat karena hampir segala sesuatu yang lain ditulis dalam C .

Java dibangun di atas C, Python dibangun di atas C (atau Java, atau .NET, dll.), Perl adalah, dll. OS ditulis dalam C, mesin virtual ditulis dalam C, kompiler ditulis dalam C, penafsir ditulis dalam C. Beberapa hal masih ditulis dalam bahasa Majelis, yang cenderung lebih cepat. Semakin banyak hal yang ditulis dalam sesuatu yang lain, yang dengan sendirinya ditulis dalam C.

Setiap pernyataan yang Anda tulis dalam bahasa lain (bukan Majelis) biasanya diterapkan di bawahnya sebagai beberapa pernyataan dalam C, yang dikompilasi ke kode mesin asli. Karena bahasa-bahasa lain cenderung ada untuk mendapatkan tingkat abstraksi yang lebih tinggi daripada bahasa C, pernyataan tambahan yang dibutuhkan dalam bahasa C cenderung berfokus pada menambah keamanan, menambah kompleksitas, dan menyediakan penanganan kesalahan. Itu sering kali merupakan hal yang baik, tetapi harganya mahal , dan namanya cepat dan besar .

Secara pribadi, saya telah menulis dalam lusinan bahasa yang mencakup sebagian besar spektrum yang tersedia, dan saya pribadi telah mencari keajaiban yang Anda isyaratkan:

Bagaimana saya bisa mendapatkan kue dan memakannya juga? Bagaimana saya bisa bermain dengan abstraksi tingkat tinggi dalam bahasa favorit saya, lalu turun ke seluk-beluk C untuk kecepatan?

Setelah beberapa tahun penelitian, jawaban saya adalah Python (pada C). Anda mungkin ingin melihatnya. Omong-omong, Anda juga dapat drop-down ke Assembly dari Python, juga (dengan bantuan kecil dari perpustakaan khusus).

Di sisi lain, kode yang buruk dapat ditulis dalam bahasa apa pun . Karenanya, kode C (atau Majelis) tidak otomatis lebih cepat. Demikian juga, beberapa trik pengoptimalan dapat membawa bagian dari kode bahasa tingkat yang lebih tinggi mendekati tingkat kinerja C. mentah. Tetapi, untuk sebagian besar aplikasi, program Anda menghabiskan sebagian besar waktunya menunggu orang atau perangkat keras, sehingga perbedaannya benar-benar tidak masalah.

Nikmati.

Rob Williams
sumber
10
Ini tidak benar-benar berlaku untuk bahasa yang dikompilasi JIT. Ini tidak seperti C # saya sedang dikompilasi ke IL yang diterjemahkan ke dalam C yang dikompilasi ke kode mesin. Tidak, IL dikompilasi dengan JIT - dan bahasa implementasi JIT tidak relevan pada saat itu. Itu hanya memproduksi kode mesin.
Jon Skeet
3
Tuhan melarang saya mempertanyakan Jon Skeet yang legendaris, tetapi tampaknya sepenuhnya relevan bahwa kode mesin yang diproduksi adalah untuk C # alih-alih C, jadi "tingkat yang lebih tinggi", memiliki lebih banyak fungsi, memiliki pemeriksaan keamanan, dll. Dan akan menjadi, karena itu, lebih lambat dari C. "setara".
Rob Williams
3
@ Jon: Saya akan mengatakan sesuatu yang serupa tetapi intinya sebenarnya agak valid karena banyak komponen inti .NET library sebenarnya benar-benar ditulis dalam C dan dengan demikian memiliki batasan kecepatan C. Akan menarik untuk melihat bagaimana ini akan berubah di masa depan.
Konrad Rudolph
1
Ini kelihatannya salah, compiler / interpreter / vms bahasa lain sering tetapi tidak selalu ditulis dalam c (atau setidaknya untuk lapisan terendah) karena c cukup cepat (dan dalam banyak kasus paling cepat).
Roman A. Taycher
2
Jawaban ini tidak benar. Seperti yang ditunjukkan di atas, itu tidak berlaku untuk bahasa JIT, tetapi juga tidak berlaku untuk bahasa dengan kompiler mereka sendiri (yang, jika upaya luar biasa dimasukkan ke dalamnya, dapat menghasilkan kode lebih cepat daripada kompiler C modern). Satu-satunya kelas bahasa yang tersisa adalah bahasa yang ditafsirkan, dan itu tidak lebih lambat dari C hanya karena mereka ditulis dalam C sendiri, tetapi karena overhead menafsirkan, tidak peduli bagaimana Anda mengirisnya dan bahkan jika penerjemah ditulis dalam kumpulan , sangat besar.
Score_Under
38

Ada banyak pertanyaan di sana - kebanyakan yang saya tidak memenuhi syarat untuk menjawab. Tetapi untuk yang terakhir ini:

apa yang menghentikan bahasa lain agar dapat dikompilasi ke biner yang berjalan setiap bit secepat C?

Dalam satu kata, Abstraksi.

C hanya satu atau 2 level abstraksi dari bahasa mesin. Bahasa Java dan .Net berada pada minimal 3 level abstraksi dari assembler. Saya tidak yakin tentang Python dan Ruby.

Biasanya, semakin banyak mainan programmer (tipe data kompleks, dll.), Semakin jauh Anda dari bahasa mesin dan semakin banyak terjemahan yang harus dilakukan.

Saya ke sana-sini tapi itulah intinya.

Perbarui ------- Ada beberapa komentar bagus pada posting ini dengan detail lebih lanjut.

Rob Allen
sumber
3
Secara teknis, Java dan .Net jauh disarikan dari bahasa mesin dari mesin yang mereka jalankan. Mereka berjalan di VM. Bahkan dengan JIT kode asli harus dipijat secara masif untuk mendapatkan sesuatu yang menyerupai kode mesin asli.
jmucchiello
1
kode .net tidak berjalan di VM. Ini berjalan sebagai instruksi asli pada platform prosesor apa pun yang menjalankannya (x86 32-bit, x86 64-bit, atau IA64).
Robert C. Barth
11
@ Robert: .net tidak menggunakan VM. .net code dikompilasi menjadi bytecode yang dijalankan oleh VM. VM mengubah bytecode menjadi instruksi asli pada saat run time.
Robert Gamble
3
Ini sangat penting untuk dicatat bahwa Java dan abstraksi bahasa OO lainnya telah mempengaruhi prosesor set instruksi. Prosesor yang lebih baru memiliki instruksi yang membuat Java berjalan lebih cepat jika java VM tahu tentang optimasi ini dan menggunakannya. Ini tidak besar, tetapi sangat membantu.
Adam Davis
1
Mungkin ThumbEE en.wikipedia.org/wiki/…
Roman A. Taycher
35

Tidak terlalu cepat C karena model biaya C transparan . Jika program C lambat, lambat dalam cara yang jelas: dengan mengeksekusi banyak pernyataan. Dibandingkan dengan biaya operasi dalam C, operasi tingkat tinggi pada objek (terutama refleksi) atau string dapat memiliki biaya yang tidak jelas.

Dua bahasa yang umumnya dikompilasi ke binari yang secepat C adalah Standar ML (menggunakan kompiler MLton ) dan Objective Caml . Jika Anda memeriksa permainan benchmark, Anda akan menemukan bahwa untuk beberapa benchmark, seperti pohon biner, versi OCaml lebih cepat dari C. (Saya tidak menemukan entri MLton.) Tetapi jangan menganggap baku tembak terlalu serius; itu adalah, seperti yang dikatakan, permainan, hasilnya sering kali mencerminkan berapa banyak upaya yang dilakukan orang dalam menyetel kode.

Norman Ramsey
sumber
Dimungkinkan untuk menulis kode yang tidak jelas mahal dalam bahasa apa pun. Hanya saja dalam beberapa bahasa, Anda harus menulis varian bagian dalam Lisp atau Forth terlebih dahulu ...
Donal Fellows
Juga Rust cocok dengan C di tolok ukur.
stark
18

C tidak selalu lebih cepat.

C lebih lambat daripada, misalnya Modern Fortran.

C sering lebih lambat dari Jawa untuk beberapa hal. (Terutama setelah kompiler JIT mencoba kode Anda)

C memungkinkan pointer aliasing terjadi, yang berarti beberapa optimasi yang baik tidak dimungkinkan. Khususnya ketika Anda memiliki beberapa unit eksekusi, ini menyebabkan data mengambil warung. Ow

Asumsi bahwa pointer berfungsi aritmatika benar-benar menyebabkan kinerja kembung lambat pada beberapa keluarga CPU (PIC khususnya!) Ini digunakan untuk menyedot yang besar pada x86 tersegmentasi.

Pada dasarnya, ketika Anda mendapatkan unit vektor, atau kompilator paralelisasi, C bau dan Fortran modern berjalan lebih cepat.

Trik programmer C seperti thunking (memodifikasi executable on the fly) menyebabkan CPU prefetch warung.

Anda mengerti maksudnya?

Dan teman baik kita, x86, mengeksekusi set instruksi yang saat ini tidak banyak berhubungan dengan arsitektur CPU yang sebenarnya. Register shadow, pengoptimal load-store, semuanya dalam CPU. Jadi C kemudian dekat dengan logam virtual. Logam asli, Intel jangan biarkan Anda melihat. (Secara historis VLIW CPU sedikit payah jadi, mungkin itu tidak terlalu buruk.)

Jika Anda memprogram dalam C pada DSP kinerja tinggi (mungkin TI DSP?), Kompiler harus melakukan beberapa hal rumit untuk membuka gulungan C di beberapa unit eksekusi paralel. Jadi dalam hal ini C tidak dekat dengan logam, tetapi dekat dengan kompiler, yang akan melakukan optimasi seluruh program. Aneh.

Dan akhirnya, beberapa CPU (www.ajile.com) menjalankan bytecodes Java di perangkat keras. C akan PITA untuk digunakan pada CPU itu.

Tim Williscroft
sumber
1
Kapan terakhir kali thunking ditulis, di C? X86 modern adalah antarmuka untuk sebagian besar RISC desain, tapi itu tak ada hubungannya dengan VLIW ...
Calyth
7
Banyak dari posting Anda mengabaikan keberadaan C99. Juga, banyak kompiler C / C ++ menawarkan kata kunci pembatasan C99 (memastikan tidak ada pointer alias) sebagai ekstensi.
Evan Teran
Saya berasumsi bahwa semua orang mengikuti / beralih ke mengikuti 25 besar CWE / SANS dan menghindari membuat desain baru dalam C. Jadi tidak ada bidang hijau C, jadi sedikit atau tidak ada C99.
Tim Williscroft
2
Bisakah Anda menunjukkan contoh ketika c lebih lambat dari Fortenberry modern?
Adam
Saya tidak yakin pernah ada waktu ketika kompiler C bersaing sangat baik dengan kompiler Fortran terbaik. Tentu saja ada banyak kode yang tidak ingin Anda tulis dalam FORTRAN 77 (apalagi 66), tetapi standar Fortran yang lebih baru semakin menyenangkan.
tfb
11

apa yang menghentikan bahasa lain agar dapat dikompilasi ke biner yang berjalan setiap bit secepat C?

Tidak ada. Bahasa modern seperti Java atau. NET lebih berorientasi pada produktivitas programmer daripada kinerja. Perangkat keras sudah murah sekarang. Juga kompilasi ke representasi perantara memberikan banyak bonus seperti keamanan, portabilitas dll. NET CLR dapat mengambil keuntungan dari perangkat keras yang berbeda - misalnya Anda tidak perlu mengoptimalkan / mengkompilasi ulang program secara manual untuk menggunakan set instruksi SSE.

aku
sumber
Saya berpendapat portabilitas di sini. Jika Anda ingin kode yang benar-benar portabel Anda akan menuliskannya dalam C dan bukan dalam bahasa lain. Kami memiliki kode yang berjalan di sekitar 25 sistem operasi. Mulai dari dos dan ThreadX dan finishing di Linux / XP menunjukkan bahasa lain yang dapat melakukan itu :)
Ilya
1
@Ilya saya tidak setuju. Sama mudahnya untuk menulis kode non-portabel dalam C. Lihat betapa menyakitkannya bagi sebagian orang untuk porting ke 64-bit. Bahasa bytecode bisa bekerja lintas platform jika Anda punya penerjemah bytecode yang tepat.
Calyth
1
@ Iya, kode C portabel adalah pengecualian daripada aturan, saya porting kode C antara platform perangkat keras / perangkat lunak yang berbeda dan tahu bahwa itu adalah mimpi buruk.
aku
Bahkan untuk kata PC bukan itu masalahnya. Lihatlah sebagian besar aplikasi lintas platform yang ditulis dalam c / c ++, sedikit di java. Untuk pengembangan tingkat rendah tertanam tidak ada kasus lain. C adalah bahasa de facto yang paling portabel.
Ilya
@aku -> PORTING kode buruk mungkin bencana saya setuju. Menulis kode portabel dalam ADVANCE - C adalah pilihan terbaik. Saya akan mengatakan C ++ adalah pilihan tetapi pergi ke platform tertanam Anda selalu akan menemukan kompiler C yang layak, untuk c ++ Anda mungkin menemukan diri Anda tanpa kompiler.
Ilya
8

Faktor utama adalah bahasa yang diketik secara statis dan dikompilasi dengan kode mesin. Juga, karena ini adalah bahasa tingkat rendah, umumnya tidak melakukan apa pun yang Anda tidak menyuruhnya.

Ini adalah beberapa faktor lain yang muncul di pikiran.

  • Variabel tidak diinisialisasi secara otomatis
  • Tidak ada batasan memeriksa array
  • Manipulasi pointer yang tidak dicentang
  • Tidak ada pemeriksaan integer overflow
  • Variabel yang diketik secara statis
  • Panggilan fungsi bersifat statis (kecuali jika Anda menggunakan pointer fungsi)
  • Penulis kompiler memiliki banyak waktu untuk meningkatkan kode pengoptimalan. Juga, program orang di C untuk tujuan mendapatkan kinerja terbaik, jadi ada tekanan untuk mengoptimalkan kode.
  • Bagian dari spesifikasi bahasa ditentukan oleh implementasi, sehingga kompiler bebas untuk melakukan hal-hal dengan cara yang paling optimal

Sebagian besar bahasa yang diketik statis dapat dikompilasi sama cepat atau lebih cepat dari C, terutama jika mereka dapat membuat asumsi bahwa C tidak bisa karena aliasing pointer, dll.

Matthew Crumley
sumber
C tingkat rendah? Saya kira itu adalah makna relatif sekarang, dibandingkan dengan Java ya tetapi dibandingkan dengan perakitan no. Pos yang bagus, membuat saya berpikir.
Mark
Anda benar, itu pasti relatif. Maksud saya adalah "dekat dengan mesin" dan tidak membantu Anda melakukan hal-hal seperti manajemen memori atau melacak ukuran array.
Matthew Crumley
2
C adalah bahasa tingkat rendah. C selalu menjadi bahasa tingkat rendah. Anda menerjemahkan kode C ke assembler tanpa banyak kesulitan.
Robert C. Barth
2
@ Robert: C dulu dianggap bahasa tingkat tinggi karena dibandingkan dengan bahasa rakitan (yang sangat umum), itu. Ini dianggap sebagai bahasa tingkat rendah dibandingkan dengan mayoritas bahasa yang digunakan saat ini.
Robert Gamble
Jujur, ini adalah jawaban yang sangat bias. Sial dekat semua programmer C melakukan pemeriksaan batas, dll. Namun C masih JAUH lebih cepat daripada C ++.
MarcusJ
8

Saya kira Anda lupa bahwa bahasa Assembly juga bahasa :)

Tetapi serius, program C lebih cepat hanya ketika programmer tahu apa yang dia lakukan. Anda dapat dengan mudah menulis program C yang berjalan lebih lambat daripada program yang ditulis dalam bahasa lain yang melakukan pekerjaan yang sama.

Alasan mengapa C lebih cepat adalah karena ia dirancang dengan cara ini. Ini memungkinkan Anda melakukan banyak hal "level bawah" yang membantu kompiler mengoptimalkan kode. Atau, haruskah kita katakan, Anda programmer bertanggung jawab untuk mengoptimalkan kode. Namun seringkali cukup rumit dan rawan kesalahan.

Bahasa lain, seperti yang lain telah disebutkan, lebih fokus pada produktivitas programmer. Secara umum diyakini bahwa waktu programmer jauh lebih mahal daripada waktu mesin (bahkan di masa lalu). Jadi sangat masuk akal untuk meminimalkan waktu yang dihabiskan programmer untuk menulis dan men-debug program alih-alih waktu menjalankan program. Untuk melakukan itu, Anda akan sedikit mengorbankan apa yang dapat Anda lakukan untuk membuat program lebih cepat karena banyak hal yang otomatis.

PolyThinker
sumber
3
Meskipun jika Anda menulis program sekali dalam C dan lagi di Majelis, versi C mungkin akan lebih cepat karena kompiler lebih pintar daripada Anda.
mk12
7

Sebagian besar, setiap instruksi C sesuai dengan instruksi assembler yang sangat sedikit. Anda pada dasarnya menulis kode mesin tingkat yang lebih tinggi, sehingga Anda memiliki kendali atas hampir semua yang dilakukan prosesor. Banyak bahasa yang dikompilasi lainnya, seperti C ++, memiliki banyak instruksi yang tampak sederhana yang dapat berubah menjadi lebih banyak kode daripada yang Anda pikirkan (fungsi virtual, copy constructor, dll.) Dan bahasa yang ditafsirkan seperti Java atau Ruby memiliki lapisan lain dari instruksi yang tidak pernah Anda lihat - Mesin Virtual atau Interpreter.

ASHelly
sumber
Dan beberapa dari bahasa tingkat tinggi ini merasa bangga karena mereka dapat menghapus sebagian besar cruft yang mereka tambahkan sejak awal. Hal-hal seperti copy elision, optimisasi nilai balik, memindahkan konstruksi / penugasan, dll. Di C ++.
cmaster - mengembalikan monica
Jadi semuanya tergantung pada jumlah instruksi perakitan yang dihasilkan dari kode. Ada lebih banyak instruksi perakitan per baris kode tingkat tinggi, semakin banyak kinerjanya?
ENDEESA
Itu mungkin penyederhanaan yang berlebihan, tetapi ada hubungan langsung antara jumlah instruksi perakitan dan kecepatan program. Ada jumlah minimum waktu untuk prosesor untuk menjalankan setiap instruksi. IMHO, bahasa yang memudahkan Anda memahami berapa banyak instruksi yang Anda tulis membantu Anda menulis kode yang lebih efisien. (Ada biaya waktu prosesor lainnya, seperti percabangan dan kehilangan cache, tetapi bahkan di sana, sedikit abstraksi membantu memperjelas apa yang dilakukan CPU).
AShelly
7

Saya tahu banyak orang mengatakannya dengan cara yang panjang lebar, tetapi:

C lebih cepat karena lebih sedikit (untuk Anda).

Daemin
sumber
Ini. Begitu benar dengan semangat C.
cmaster - mengembalikan monica
7

C ++ lebih cepat rata-rata (seperti awalnya, sebagian besar superset dari C, meskipun ada beberapa perbedaan). Namun, untuk tolok ukur tertentu, seringkali ada bahasa lain yang lebih cepat.

https://benchmarksgame-team.pages.debian.net/benchmarksgame/

fannjuch-redux tercepat di Scala

n-bodydan fastalebih cepat di Ada.

spectral-norm tercepat di Fortran.

reverse-complement, mandelbrotdan pidigitstercepat di ATS.

regex-dna tercepat di JavaScript.

chameneou-redux paling cepat adalah Java 7.

thread-ring tercepat di Haskell.

Sisa tolok ukur tercepat di C atau C ++.

Peter Lawrey
sumber
"karena ini adalah set super C" - Tidak, C ++ bukan superset dari C.
PP
1
extern "C"tidak ada hubungannya dengan C ++ menjadi superset dari C.
PP
2
Ini seperti mengatakan system("bash script.sh");bekerja untuk skrip bash, dan karenanya C adalah superset dari bash. extern "C"menyediakan tautan C dalam C ++ karena namanya mangling. Sedangkan memanggil X sebagai superset dari Y berarti segala sesuatu yang dapat dilakukan dalam Y juga dapat dilakukan dalam X, yang tidak berlaku untuk C ++. Ada beberapa konstruksi bahasa yang valid dalam C tetapi tidak dalam C ++.
PP
1
@PP Tidak ada dalam standar C ++ yang mengamanatkan bahwa itu bashadalah program baris perintah yang tersedia. Jika ya dan menyertakan versi / spesifikasi bash apa yang perlu didukung, saya akan menganggapnya superset.
Peter Lawrey
1
itu mudah untuk menulis kode C yang bukan kode C ++, misalnyastruct foo { int: this; }; typedef float foo;
Jasen
6

Banyak dari jawaban ini memberikan alasan yang valid mengapa C adalah, atau tidak, lebih cepat (baik dalam skenario umum atau khusus). Tidak dapat dipungkiri bahwa:

  • Banyak bahasa lain menyediakan fitur otomatis yang kami anggap remeh. Pengecekan batas, pemeriksaan jenis run-time, dan manajemen memori otomatis, misalnya, tidak datang secara gratis. Setidaknya ada beberapa biaya yang terkait dengan fitur-fitur ini, yang mungkin tidak kita pikirkan — atau bahkan sadari — ketika menulis kode yang menggunakan fitur-fitur ini.
  • Langkah dari sumber ke mesin sering tidak langsung dalam bahasa lain seperti dalam C.
  • OTOH, untuk mengatakan bahwa kode C yang dikompilasi dieksekusi lebih cepat daripada kode lain yang ditulis dalam bahasa lain adalah generalisasi yang tidak selalu benar. Contoh tandingan mudah ditemukan (atau dibuat-buat).

Meskipun demikian, ada hal lain yang saya perhatikan bahwa, saya pikir, mempengaruhi kinerja komparatif C vs banyak bahasa lain lebih besar daripada faktor lainnya. Yakni:

Bahasa lain sering membuatnya lebih mudah untuk menulis kode yang dieksekusi lebih lambat. Seringkali, itu bahkan didorong oleh filosofi desain bahasa. Konsekuensi: seorang programmer C lebih cenderung menulis kode yang tidak melakukan operasi yang tidak perlu.

Sebagai contoh, pertimbangkan program Windows sederhana di mana satu jendela utama dibuat. Versi AC akan mengisi WNDCLASS[EX]struktur yang akan diteruskan RegisterClass[Ex], lalu memanggil CreateWindow[Ex]dan memasukkan loop pesan. Kode yang sangat disederhanakan dan disingkat mengikuti:

WNDCLASS wc;
MSG      msg;

wc.style         = 0;
wc.lpfnWndProc   = &WndProc;
wc.cbClsExtra    = 0;
wc.cbWndExtra    = 0;
wc.hInstance     = hInstance;
wc.hIcon         = NULL;
wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName  = NULL;
wc.lpszClassName = "MainWndCls";

RegisterClass(&wc);

CreateWindow("MainWndCls", "", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
             CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

while(GetMessage(&msg, NULL, 0, 0)){
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

Program yang setara dalam C # bisa jadi hanya satu baris kode:

Application.Run(new Form());

Satu baris kode ini menyediakan semua fungsi yang dilakukan hampir 20 baris kode C, dan menambahkan beberapa hal yang kami tinggalkan, seperti pengecekan kesalahan. Pustaka yang lebih kaya dan lebih lengkap (dibandingkan dengan yang digunakan dalam proyek C khas) melakukan banyak pekerjaan bagi kami, membebaskan waktu kami untuk menulis lebih banyak potongan kode yang terlihat pendek bagi kami tetapi melibatkan banyak langkah di belakang layar.

Tapi perpustakaan yang kaya memungkinkan kode mudah dan cepat mengasapi bukan maksud saya. Maksud saya lebih jelas ketika Anda mulai memeriksa apa yang sebenarnya terjadi ketika one-liner kecil kami benar-benar dieksekusi. Untuk bersenang-senang kadang-kadang, aktifkan akses sumber .NET di Visual Studio 2008 atau lebih tinggi, dan masuk ke baris-sederhana di atas. Salah satu permata kecil yang menyenangkan yang akan Anda temui adalah komentar ini di pengambil untuk Control.CreateParams:

// In a typical control this is accessed ten times to create and show a control.
// It is a net memory savings, then, to maintain a copy on control.
// 
if (createParams == null) {
    createParams = new CreateParams(); 
} 

Sepuluh kali . Informasi yang kira-kira setara dengan jumlah dari apa yang disimpan dalam suatu WNDCLASSEXstruktur dan apa yang diteruskan CreateWindowExdiambil dari Controlkelas sepuluh kali sebelum disimpan dalam suatu WNDCLASSEXstruktur dan diteruskan ke RegisterClassExdan CreateWindowEx.

Secara keseluruhan, jumlah instruksi yang dieksekusi untuk melakukan tugas yang sangat mendasar ini adalah 2-3 kali lipat lebih banyak di C # daripada di C. Bagian dari ini adalah karena penggunaan perpustakaan kaya fitur, yang perlu digeneralisasi, dibandingkan kode C sederhana yang melakukan persis apa yang kita butuhkan dan tidak lebih. Tetapi bagian dari itu adalah karena fakta bahwa sifat kerangka kerja .NET yang termodulasiasikan dan berorientasi objek, cocok untuk banyak pengulangan eksekusi yang sering dihindari oleh pendekatan prosedural.

Saya tidak mencoba untuk memilih C # atau framework .NET. Saya juga tidak mengatakan bahwa modularisasi, generalisasi, fitur perpustakaan / bahasa, OOP, dll. Adalah hal-hal buruk . Saya biasa melakukan sebagian besar pengembangan saya di C, kemudian di C ++, dan paling akhir di C #. Demikian pula, sebelum C, saya menggunakan kebanyakan perakitan. Dan dengan setiap langkah "lebih tinggi" bahasa saya berjalan, saya menulis program yang lebih baik, lebih dapat dikelola, lebih kuat dalam waktu yang lebih singkat. Namun, mereka cenderung melakukan sedikit lebih lambat.

P Ayah
sumber
2
Itu adalah masalah API, bukan masalah bahasa.
Arafangion
1
@Arafangion: Saya mengerti apa yang Anda katakan, tapi itu agak melenceng. Pustaka yang kaya fitur diaktifkan (dan, dengan cara, diminta) oleh bahasa yang kaya fitur. Dan bukan hanya perpustakaan. Perpustakaan hanyalah contoh dari penggunaan umum bahasa. Kode aplikasi umum dalam bahasa apa pun umumnya memiliki kemiripan dengan perpustakaan yang biasanya digunakan dalam bahasa itu. Ini benar-benar lebih dari pola pikir yang dipupuk oleh bahasa. Misalnya, bahasa OO umumnya menghabiskan lebih banyak waktu untuk mengalokasikan, membangun, merusak, dan menghapus alokasi objek daripada bahasa dengan dukungan OOP yang lebih sedikit.
P Ayah
Saya akan mengakui bahwa pilihan bahasa yang diberikan umumnya menyiratkan platform dan perpustakaan tertentu, itulah sebabnya saya membuat komentar itu (sehingga pembaca akan lebih sadar), tetapi yang mengatakan, menggunakan (misalnya) C ++ pada windows adalah binatang yang sangat berbeda dengan, katakanlah, C ++ di linux dan berbeda lagi dengan C ++ di Android. Contoh lain adalah Python - kami memiliki CPython, Jython, PyPy, dan IronPython - yang semuanya menggunakan pustaka yang sangat berbeda.
Arafangion
Tetapi menggunakan salah satu dari Python ini, pengembang akan cenderung untuk menulis aplikasi dengan cara tertentu. Misalnya, mereka dapat membaca dan menulis dari file teks, membuat objek baru dengan data yang mereka baca. Di C, di sisi lain, pengembang akan lebih mungkin melakukan alokasi satu kali dari array struct, dan membaca dan menulis struct tersebut dari file biner. Ini, tentu saja, hanyalah contoh yang dibuat-buat yang mencoba mengilustrasikan poin yang saya coba buat tentang pola pikir .
P Ayah
6

Saya tidak berpikir ada orang yang menyebutkan fakta bahwa lebih banyak upaya telah dimasukkan ke dalam kompiler C daripada kompiler lain, dengan pengecualian Jawa.

C sangat mampu mengoptimalkan karena banyak alasan yang telah dinyatakan - lebih dari hampir semua bahasa lain. Jadi jika jumlah upaya yang sama dimasukkan ke kompiler bahasa lain, C mungkin masih akan keluar di atas.

Saya pikir setidaknya ada satu bahasa kandidat yang dengan usaha dapat dioptimalkan lebih baik daripada C dan dengan demikian kita bisa melihat implementasi yang menghasilkan biner lebih cepat. Saya sedang memikirkan digital mars D karena pembuatnya berhati-hati untuk membangun bahasa yang berpotensi dioptimalkan lebih baik daripada C. Mungkin ada bahasa lain yang memiliki kemungkinan ini. Namun saya tidak dapat membayangkan bahwa bahasa apa pun akan memiliki kompiler lebih dari hanya beberapa persen lebih cepat daripada kompiler C terbaik. Saya ingin salah.

Saya pikir "buah tergantung rendah" sebenarnya akan dalam bahasa yang dirancang untuk MUDAH bagi manusia untuk dioptimalkan. Seorang programmer yang terampil dapat membuat bahasa apa pun berjalan lebih cepat - tetapi kadang-kadang Anda harus melakukan hal-hal konyol atau menggunakan konstruksi yang tidak alami untuk mewujudkannya. Meskipun akan selalu membutuhkan upaya, bahasa yang baik harus menghasilkan kode yang relatif cepat tanpa harus terobsesi dengan cara penulisan program.

Penting juga (setidaknya bagi saya) bahwa kode kasus terburuk cenderung cepat. Ada banyak "bukti" di web bahwa Java sama cepat atau lebih cepat dari C, tetapi itu didasarkan pada contoh memetik ceri. Saya bukan penggemar C, tapi saya tahu bahwa APA SAJA yang saya tulis dalam C akan berjalan dengan baik. Dengan Java, "mungkin" akan berjalan dalam 15% dari kecepatan, biasanya dalam 25% tetapi dalam beberapa kasus bisa jauh lebih buruk. Setiap kasus di mana itu sama cepat atau dalam beberapa persen biasanya karena sebagian besar waktu dihabiskan dalam kode perpustakaan yang sangat dioptimalkan C pula.

Mengenakan
sumber
5

Ini sebenarnya sedikit kepalsuan yang diabadikan. Memang benar bahwa program C sering kali lebih cepat, hal ini tidak selalu terjadi, terutama jika programmer C tidak pandai melakukannya.

Satu lubang mencolok yang cenderung dilupakan orang adalah ketika program harus memblokir semacam IO, seperti input pengguna dalam program GUI apa pun. Dalam kasus ini, tidak masalah bahasa apa yang Anda gunakan karena Anda dibatasi oleh kecepatan data bisa masuk, bukan seberapa cepat Anda bisa memprosesnya. Dalam hal ini, tidak masalah jika Anda menggunakan C, Java, C # atau bahkan Perl; Anda tidak bisa berjalan lebih cepat daripada data bisa masuk.

Hal utama lainnya adalah bahwa menggunakan pengumpulan sampah dan tidak menggunakan pointer yang tepat memungkinkan mesin virtual untuk membuat sejumlah optimasi tidak tersedia dalam bahasa lain. Misalnya, JVM mampu memindahkan objek di heap untuk mendefrag itu. Ini membuat alokasi di masa depan jauh lebih cepat karena indeks berikutnya hanya dapat digunakan daripada mencarinya di tabel. JVM modern juga tidak harus benar-benar mengalokasikan memori; sebagai gantinya, mereka hanya memindahkan objek hidup di sekitar ketika mereka GC dan memori yang dihabiskan dari objek mati dipulihkan pada dasarnya gratis.

Ini juga memunculkan poin menarik tentang C dan bahkan lebih lagi di C ++. Ada semacam filosofi desain "Jika Anda tidak membutuhkannya, Anda tidak membayarnya." Masalahnya adalah bahwa jika Anda menginginkannya, Anda harus membayar mahal untuk itu. Sebagai contoh, implementasi vtable di Java cenderung jauh lebih baik daripada implementasi C ++, jadi panggilan fungsi virtual jauh lebih cepat. Di sisi lain, Anda tidak punya pilihan selain menggunakan fungsi virtual di Jawa dan mereka masih membutuhkan biaya, tetapi dalam program yang menggunakan banyak fungsi virtual, biaya yang berkurang bertambah.

James
sumber
1
"Implementasi vtable di Java cenderung jauh lebih baik daripada implementasi C ++, jadi panggilan fungsi virtual jauh lebih cepat." Bagaimana Anda bisa bergerak lebih cepat dari MOV EAX, [ECX]; CALL [EAX + someindex]; ? Kecuali Anda dapat memanggil fungsi tanpa melihatnya, ini terlihat cukup optimal.
Frans-Willem
@ Trans - kompiler JIT (seperti Java HotSpot) dapat menyejajarkan lookup vtable jika menentukan objek yang diberikan selalu dari tipe yang diberikan. C ++ juga akan melakukan ini jika mengetahui info yang sama pada waktu kompilasi, tetapi lebih mudah untuk melakukan optimasi ini dengan Java bytecode daripada dengan instruksi mesin x86.
Tom
6
@James - Berargumen "I / O membuat masalah kinerja kurang" tidak membatalkan pernyataan "C lebih cepat daripada bahasa lain". Itu bukan lubang yang mencolok, itu argumen yang konyol.
Tom
Akan lebih baik menggunakan penanganan string C (dan juga pustaka C standar) sebagai contoh, karena itu adalah area di mana C buruk. Sebagian besar bahasa lain lebih baik, bahkan dengan kode awal yang sederhana.
Donal Fellows
@DonalFellows fungsi mem * dapat lebih cepat dari fungsi str * pada beberapa tugas, tetapi penanganan string lebih efisien jika dilakukan dengan hati-hati. Sudahkah Anda memiliki patokan tertentu?
Jasen
4

Ini bukan tentang bahasa sebagai alat dan perpustakaan. Pustaka dan kompiler yang tersedia untuk C jauh lebih tua daripada untuk bahasa yang lebih baru. Anda mungkin berpikir ini akan membuat mereka lebih lambat, tetapi au contraire.

Perpustakaan-perpustakaan ini ditulis pada saat pemrosesan daya dan memori berada pada premium. Mereka harus ditulis dengan sangat efisien agar dapat bekerja sama sekali. Pengembang kompiler C juga telah lama bekerja dalam semua jenis optimisasi pintar untuk prosesor yang berbeda. Kedewasaan C dan adopsi yang luas menjadikan keuntungan yang signifikan di atas bahasa lain pada usia yang sama. Ini juga memberi C keunggulan kecepatan dibandingkan alat yang lebih baru yang tidak menekankan kinerja mentah sebanyak yang harus dilakukan C.

Dave Swersky
sumber
4

Kurangnya abstraksi adalah apa yang membuat C lebih cepat. Jika Anda menulis pernyataan keluaran, Anda tahu persis apa yang terjadi. Jika Anda menulis pernyataan keluaran dalam java, file tersebut dikompilasi ke file kelas yang kemudian dijalankan pada mesin virtual yang memperkenalkan lapisan abstraksi. Kurangnya fitur berorientasi objek sebagai bagian dari bahasa juga meningkatkan kecepatannya untuk mengurangi kode yang dihasilkan. Jika Anda menggunakan C sebagai bahasa berorientasi objek maka Anda melakukan semua pengkodean untuk hal-hal seperti kelas, inharitence, dll. Ini berarti daripada membuat sesuatu yang cukup umum untuk semua orang dengan jumlah kode dan kinerja yang mengharuskan Anda hanya menulis apa yang Anda butuhkan untuk menyelesaikan pekerjaan.

Jared
sumber
4

Luar biasa melihat "C / C ++ lama harus lebih cepat dari Jawa karena Java ditafsirkan" mitos masih hidup dan menendang. Ada artikel yang akan kembali beberapa tahun , dan juga yang lebih baru , yang menjelaskan dengan konsep atau pengukuran mengapa ini tidak selalu terjadi .

Implementasi mesin virtual saat ini (dan bukan hanya JVM, omong-omong) dapat mengambil keuntungan dari informasi yang dikumpulkan selama eksekusi program untuk secara dinamis menyempurnakan kode saat dijalankan, menggunakan berbagai teknik:

  • render metode yang sering ke kode mesin,
  • inlining metode kecil,
  • penyesuaian penguncian

dan berbagai penyesuaian lainnya berdasarkan pada mengetahui apa yang sebenarnya dilakukan kode, dan pada karakteristik aktual dari lingkungan tempat kode itu dijalankan.

joel.neely
sumber
Saya setuju bahwa Java telah membuat peningkatan kinerja yang signifikan selama beberapa tahun terakhir yang membawanya lebih dekat ke C dalam hal kinerja mentah, tetapi akan memakan waktu cukup lama untuk menghidupkan kenyataan bahwa itu sangat lambat begitu lama. Tapi siapa yang berbicara tentang Jawa?
Robert Gamble
Java adalah "bahasa lain" yang dirujuk oleh OP, bukan?
Robert C. Barth
@ Robert: "bahasa lain", jamak, tidak disebutkan bahasa spesifik selain C. Bagaimana Anda bisa membaca "Java" dari itu?
Robert Gamble
@ Robert: Beberapa jawaban yang telah diposting sebelum saya temui pertanyaan itu berbicara tentang Java (atau bahasa lain yang implementasinya sering melalui penerjemah atau VM).
joel.neely
3
@ Joel - Jika Anda mengetahui perangkat keras target Anda, sebagian besar optimasi yang dapat dilakukan JVM saat runtime juga dapat dilakukan dengan menggunakan optimasi dipandu profil dengan C atau C ++. Itu membuat perbedaan besar , dan umumnya mendorong C dan C ++ kembali memimpin, karena mereka tidak harus "belajar" saat mengeksekusi.
Tom
4

Kode yang paling cepat dijalankan adalah kode mesin yang dibuat dengan tangan. Assembler akan hampir sama baiknya. Keduanya level sangat rendah dan dibutuhkan banyak kode penulisan untuk melakukan sesuatu. C adalah assembler kecil di atas. Anda masih memiliki kemampuan untuk mengontrol hal-hal pada tingkat yang sangat rendah di mesin yang sebenarnya, tetapi ada abstraksi yang cukup membuat penulisan lebih cepat dan lebih mudah daripada assembler. Bahasa lain seperti C # dan JAVA bahkan lebih abstrak. Sementara Assembler dan kode mesin disebut bahasa tingkat rendah, C # dan JAVA (dan banyak lainnya) disebut bahasa tingkat tinggi. C kadang-kadang disebut bahasa tingkat menengah.

Jim C
sumber
Saat membaca jawaban Anda, hanya dua kata di seluruh paragraf yang menarik pandangan saya ke arah mereka, seperti magnet yang menarik logam. Kata itu adalah JAWA, dua kali dalam paragraf. Belum pernah melihatnya sebelum ditulis dalam huruf
kapital
3

Jangan mengambil kata seseorang untuk itu, lihat pembongkaran untuk C dan bahasa pilihan Anda dalam setiap bagian penting kinerja kode Anda. Saya pikir Anda bisa melihat di jendela pembongkaran saat runtime di Visual Studio untuk melihat. Net dibongkar. Seharusnya mungkin jika rumit untuk Java menggunakan windbg, meskipun jika Anda melakukannya dengan. Net banyak masalah akan sama.

Saya tidak suka menulis dalam C jika saya tidak perlu, tetapi saya pikir banyak dari klaim yang dibuat dalam jawaban ini bahwa menggembar-gemborkan kecepatan bahasa selain C dapat dikesampingkan dengan hanya membongkar rutinitas yang sama di C dan dalam bahasa pilihan tingkat tinggi Anda, terutama jika banyak data terlibat seperti yang umum dalam aplikasi penting kinerja. Fortran mungkin pengecualian dalam bidang keahliannya, tidak tahu. Apakah levelnya lebih tinggi dari C?

Pertama kali saya membandingkan kode JITed dengan kode asli diselesaikan setiap dan semua pertanyaan apakah. Kode bersih dapat berjalan sebanding dengan kode C. Level ekstra abstraksi dan semua pemeriksaan keselamatan datang dengan biaya yang signifikan. Biaya yang sama mungkin akan berlaku untuk Java, tetapi jangan mengambil kata saya untuk itu, cobalah pada sesuatu di mana kinerja sangat penting. (Adakah yang cukup tahu tentang Java JITed untuk menemukan prosedur yang dikompilasi dalam memori? Ini tentunya harus dimungkinkan)


sumber
2

1) Seperti yang orang lain katakan, C tidak terlalu banyak untuk Anda. Tidak ada variabel inisialisasi, tidak ada batas array memeriksa, tidak ada manajemen memori, dll. Fitur-fitur dalam bahasa lain biaya memori dan siklus CPU yang tidak menghabiskan C.

2) Jawaban yang mengatakan bahwa C kurang abstrak dan karena itu lebih cepat hanya setengah benar saya pikir. Secara teknis, jika Anda memiliki "kompiler yang cukup maju" untuk bahasa X, maka bahasa X dapat mendekati atau menyamai kecepatan C. Perbedaannya dengan C adalah karena ia memetakan dengan sangat jelas (jika Anda telah mengambil kursus arsitektur) dan langsung ke bahasa assembly yang bahkan kompiler naif dapat melakukan pekerjaan yang layak. Untuk sesuatu seperti Python, Anda memerlukan kompiler yang sangat canggih untuk memprediksi kemungkinan jenis objek dan menghasilkan kode mesin dengan cepat - semantik C cukup sederhana sehingga kompiler sederhana dapat melakukannya dengan baik.

Joseph Garvin
sumber
2

Kembali ke masa lalu, hanya ada dua jenis bahasa: dikompilasi dan ditafsirkan.

Bahasa yang dikompilasi menggunakan "kompiler" untuk membaca sintaksis bahasa dan mengkonversinya menjadi kode bahasa assembly yang identik, yang dapat dari sekadar langsung pada CPU. Bahasa yang ditafsirkan menggunakan beberapa skema yang berbeda, tetapi pada dasarnya sintaksis bahasa diubah menjadi bentuk peralihan, dan kemudian dijalankan dalam "penerjemah", lingkungan untuk mengeksekusi kode.

Jadi, dalam arti tertentu, ada "lapisan" lain - penerjemah - antara kode dan mesin. Dan, seperti yang selalu terjadi di komputer, lebih banyak berarti lebih banyak sumber daya digunakan. Penerjemah lebih lambat, karena mereka harus melakukan lebih banyak operasi.

Baru-baru ini, kami telah melihat lebih banyak bahasa hibrida seperti Jawa, yang menggunakan kompiler dan juru bahasa untuk membuatnya bekerja. Memang rumit, tetapi JVM lebih cepat, lebih canggih, dan jauh lebih dioptimalkan daripada penterjemah lama, sehingga JVM memiliki perubahan kinerja yang jauh lebih baik (seiring waktu) lebih dekat dengan kode yang langsung dikompilasi. Tentu saja, kompiler yang lebih baru juga memiliki trik optimisasi yang lebih mewah sehingga mereka cenderung menghasilkan kode yang jauh lebih baik daripada sebelumnya. Tetapi sebagian besar optimasi, paling sering (meskipun tidak selalu) membuat beberapa jenis trade-off sehingga mereka tidak selalu lebih cepat dalam semua situasi. Seperti yang lainnya, tidak ada yang datang secara gratis, sehingga pengoptimal harus membual dari suatu tempat (walaupun sering kali menggunakan kompilasi-waktu CPU untuk menghemat runtime CPU).

Kembali ke C, itu adalah bahasa yang sederhana, yang dapat dikompilasi menjadi perakitan yang cukup optimal dan kemudian dijalankan langsung pada mesin target. Di C, jika Anda menambah bilangan bulat, kemungkinan besar itu hanya satu langkah assembler di CPU, di Jawa, namun, itu bisa menjadi jauh lebih banyak dari itu (dan dapat mencakup sedikit pengumpulan sampah juga: -) C menawarkan Anda sebuah abstraksi yang jauh lebih dekat ke mesin (assembler adalah yang terdekat), tetapi Anda akhirnya harus melakukan lebih banyak pekerjaan untuk membuatnya berjalan dan tidak terlindungi, mudah digunakan atau ramah kesalahan. Sebagian besar bahasa lain memberi Anda abstraksi yang lebih tinggi dan mengurus lebih banyak detail yang mendasari untuk Anda, tetapi sebagai ganti fungsi lanjutannya, mereka membutuhkan lebih banyak sumber daya untuk dijalankan. Ketika Anda menggeneralisasi beberapa solusi, Anda harus menangani rentang komputasi yang lebih luas,

Paul.

Paul W. Homer
sumber
"Dalam C, jika Anda menambah bilangan bulat, kemungkinan besar itu hanya satu langkah assembler di CPU" Tidak sepenuhnya benar. Jika integer ini tidak ada dalam register CPU, maka Anda perlu memiliki kode mesin untuk mengambilnya dari memori, menambahkannya, menulisnya kembali ke dalam memori. Tentang hal yang sama akan terjadi ketika menjalankan kode Java. Dan saya tidak mengerti mengapa "++ i" akan memicu sendiri siklus GC.
quant_dev
@quant_dev: "Anda .. punya ... untuk mengambilnya dari memori, menambahkannya, menulisnya kembali ...". Mungkin tidak. X86, misalnya, memiliki instruksi yang beroperasi pada data dalam memori. ++imungkin dikompilasi ke "add [ebp - 8], 1". Bukan untuk mengatakan bahwa mengambil, kenaikan, toko masih belum terjadi, tetapi ini diurus oleh CPU, dan hanya satu instruksi, seperti kata Paul.
P Daddy
... yang masih tidak relevan dari POV kinerja, karena mungkin hanya satu instruksi, tetapi masih melibatkan menunggu data sampai ke CPU. Tembolok merindukan dan semua itu.
quant_dev
Tidak, saya tidak akan mengatakan itu tidak relevan. Satu instruksi CPU biasanya menempati lebih sedikit byte kode daripada banyak instruksi CPU, menghasilkan kinerja cache yang lebih baik pada segmen kode. Satu instruksi CPU juga memakan lebih sedikit ruang pada pipeline CPU, dan beberapa langkah (fetch, increment, store) dapat ditangani — mungkin secara paralel — dengan tahapan pipeline terpisah. Bahkan, beberapa bagian dari suatu operasi bahkan dapat dilewati jika mereka dapat digabung dengan operasi lain di dalam pipa. Misalnya, menyimpan nilai dapat digabung dengan pemuatan berikutnya dengan nilai yang sama.
P Ayah
2

Mengesampingkan teknik optimasi canggih seperti optimasi hot-spot , pra-kompilasi meta-algoritma , dan berbagai bentuk paralelisme , kecepatan dasar bahasa berkorelasi kuat dengan kompleksitas di balik layar yang diperlukan untuk mendukung operasi yang biasanya ditentukan dalam loop batin .

Mungkin yang paling jelas adalah memeriksa validitas pada referensi memori tidak langsung - seperti memeriksa pointer nulldan memeriksa indeks terhadap batasan array. Sebagian besar bahasa tingkat tinggi melakukan pemeriksaan ini secara implisit, tetapi C tidak. Namun, ini tidak selalu merupakan batasan mendasar dari bahasa-bahasa lain ini - kompiler yang cukup pintar mungkin dapat menghapus pemeriksaan ini dari loop dalam suatu algoritma melalui beberapa bentuk gerakan kode loop-invariant .

Keuntungan yang lebih mendasar dari C (dan pada tingkat yang sama C ++ yang terkait erat) adalah ketergantungan yang besar pada alokasi memori berbasis stack , yang secara inheren cepat untuk alokasi, deallokasi, dan akses. Dalam C (dan C ++) tumpukan panggilan utama dapat digunakan untuk alokasi primitif, array, dan agregat ( struct/ class).

Sementara C memang menawarkan kemampuan untuk mengalokasikan memori secara dinamis dengan ukuran dan masa pakai yang sewenang-wenang (menggunakan apa yang disebut 'tumpukan'), hal itu dihindari secara default (tumpukan digunakan sebagai gantinya).

Menariknya, kadang-kadang mungkin untuk mereplikasi strategi alokasi memori C dalam lingkungan runtime bahasa pemrograman lain. Ini telah ditunjukkan oleh asm.js , yang memungkinkan kode yang ditulis dalam C atau C ++ untuk diterjemahkan ke dalam subset dari JavaScript dan berjalan dengan aman di lingkungan browser web - dengan kecepatan yang hampir sama dengan aslinya.


Sebagai tambahan, area lain di mana C dan C ++ mengalahkan sebagian besar bahasa lain untuk kecepatan adalah kemampuan untuk berintegrasi mulus dengan set instruksi mesin asli. Contoh penting dari hal ini adalah ketersediaan (kompiler dan platform tergantung) dari intrinsik SIMD yang mendukung konstruksi algoritme kustom yang mengambil keuntungan dari perangkat keras pemrosesan paralel yang kini hampir di mana-mana - sambil tetap menggunakan abstraksi alokasi data yang disediakan oleh bahasa (lebih rendah). alokasi alokasi -level dikelola oleh kompiler).

bangsawan
sumber
1
Beberapa keunggulan alokasi memori C ini mungkin juga dapat direplikasi dalam bahasa lain oleh kompiler yang pintar (lihat di sini ). Saya mendapat kesan, bahwa ini entah bagaimana secara struktural sangat sulit dilakukan - terutama untuk tipe data non-primitif. Posting ini menyebutkan gagasan objek yang tidak melarikan diri yang dapat ditumpuk-ditumpuk sebagai pengoptimalan di Jawa.
nobar
2

Saya telah menemukan jawaban di tautan tentang mengapa beberapa bahasa lebih cepat dan ada yang lebih lambat, saya harap ini akan lebih jelas tentang mengapa C atau C ++ lebih cepat daripada yang lain, Ada beberapa bahasa lain yang lebih cepat dari C, tapi kami tidak bisa gunakan semuanya. Beberapa penjelasan -

Salah satu alasan utama mengapa Fortran tetap penting adalah karena ia cepat: angka-angka rutinitas yang ditulis dalam Fortran cenderung lebih cepat daripada rutinitas yang setara yang ditulis dalam kebanyakan bahasa lain. Bahasa yang bersaing dengan Fortran di ruang ini — C dan C ++ - digunakan karena mereka bersaing dengan kinerja ini.

Ini menimbulkan pertanyaan: mengapa? Ada apa dengan C ++ dan Fortran yang membuatnya cepat, dan mengapa mereka mengungguli bahasa populer lainnya, seperti Java atau Python?

Menafsirkan versus mengkompilasi Ada banyak cara untuk mengategorikan dan mendefinisikan bahasa pemrograman, sesuai dengan gaya pemrograman yang mereka dorong dan fitur yang mereka tawarkan. Saat melihat kinerja, perbedaan tunggal terbesar adalah antara bahasa yang ditafsirkan dan yang dikompilasi.

Kesenjangannya tidak sulit; sebaliknya, ada spektrum. Di satu sisi, kami memiliki bahasa kompilasi tradisional, grup yang mencakup Fortran, C, dan C ++. Dalam bahasa ini, ada tahap kompilasi diskrit yang menerjemahkan kode sumber suatu program ke dalam bentuk yang dapat dieksekusi yang dapat digunakan prosesor.

Proses kompilasi ini memiliki beberapa langkah. Kode sumber dianalisis dan diuraikan. Kesalahan pengkodean dasar seperti kesalahan ketik dan kesalahan ejaan dapat dideteksi pada saat ini. Kode yang diurai digunakan untuk menghasilkan representasi dalam-memori, yang juga dapat digunakan untuk mendeteksi kesalahan — kali ini, kesalahan semantik, seperti fungsi panggilan yang tidak ada, atau mencoba melakukan operasi aritmatika pada string teks.

Representasi dalam memori ini kemudian digunakan untuk menggerakkan pembuat kode, bagian yang menghasilkan kode yang dapat dieksekusi. Optimasi kode, untuk meningkatkan kinerja kode yang dihasilkan, dilakukan pada berbagai waktu dalam proses ini: optimasi tingkat tinggi dapat dilakukan pada representasi kode, dan optimasi tingkat yang lebih rendah digunakan pada output pembuat kode.

Sebenarnya mengeksekusi kode terjadi nanti. Seluruh proses kompilasi hanya digunakan untuk membuat sesuatu yang dapat dieksekusi.

Di ujung yang berlawanan, kami memiliki juru bahasa. Penerjemah akan menyertakan tahap penguraian mirip dengan kompiler, tetapi ini kemudian digunakan untuk mengarahkan eksekusi langsung, dengan program yang sedang dijalankan segera.

Penerjemah yang paling sederhana memiliki kode yang dapat dieksekusi di dalamnya yang sesuai dengan berbagai fitur yang didukung bahasa — sehingga akan memiliki fungsi untuk menambahkan angka, menggabungkan string, apa pun yang dimiliki bahasa tertentu. Saat mem-parsing kode, itu akan mencari fungsi yang sesuai dan menjalankannya. Variabel yang dibuat dalam program akan disimpan dalam semacam tabel pencarian yang memetakan nama mereka ke data mereka.

Contoh paling ekstrim dari gaya interpreter adalah sesuatu seperti file batch atau skrip shell. Dalam bahasa-bahasa ini, kode yang dapat dieksekusi seringkali bahkan tidak dibangun ke dalam interpreter itu sendiri, tetapi agak terpisah, program mandiri.

Jadi mengapa ini membuat perbedaan untuk kinerja? Secara umum, setiap lapisan tipuan mengurangi kinerja. Sebagai contoh, cara tercepat untuk menambahkan dua angka adalah dengan memasukkan kedua angka tersebut dalam register dalam prosesor, dan menggunakan instruksi tambahan prosesor. Itulah yang dapat dilakukan oleh program yang dikompilasi; mereka dapat memasukkan variabel ke dalam register dan memanfaatkan instruksi prosesor. Tetapi dalam program yang ditafsirkan, penambahan yang sama mungkin membutuhkan dua pencarian dalam tabel variabel untuk mengambil nilai yang akan ditambahkan, kemudian memanggil fungsi untuk melakukan penambahan. Fungsi itu mungkin sangat baik menggunakan instruksi prosesor yang sama seperti program yang dikompilasi menggunakan untuk melakukan penambahan yang sebenarnya, tetapi semua pekerjaan tambahan sebelum instruksi tersebut benar-benar dapat digunakan membuat segalanya lebih lambat.

Jika Anda ingin tahu lebih banyak, silakan periksa Sumber

unikNt
sumber
1

Beberapa algoritma C ++ lebih cepat daripada C, dan beberapa implementasi algoritma atau pola desain dalam bahasa lain bisa lebih cepat dari C.

Ketika orang mengatakan bahwa C itu cepat, dan kemudian berbicara tentang bahasa lain, mereka umumnya menggunakan kinerja C sebagai tolok ukur.

Arafangion
sumber
2
"Beberapa algoritma C ++ lebih cepat daripada C" tidak masuk akal. "Algoritma C ++" apa pun dapat ditulis dalam C dan sebaliknya. Algoritma adalah agnostik bahasa. C ++ pada dasarnya menambahkan fitur ke C - dan tidak satu pun dari fitur-fitur baru ini mengarah ke algoritma yang lebih cepat (meskipun mereka mungkin lebih mudah untuk menulis).
Joseph Garvin
1
Teguran klasik adalah std :: sort algoritme .. std :: sort lebih cepat daripada algoritma sortir apa pun di C - satu-satunya cara untuk mendapatkan kinerja yang sama dalam C adalah dengan meng-hard-code-nya di mana pun Anda inginkan atau menggunakan makro - dan bahkan kemudian kompiler memiliki lebih sedikit informasi untuk dioptimalkan.
Arafangion
1

Dengan kompiler optimisasi modern, sangat tidak mungkin bahwa program C murni akan menjadi jauh lebih cepat daripada dikompilasi .net kode, jika sama sekali. Dengan peningkatan produktivitas yang diberikan kerangka kerja seperti .net kepada pengembang, Anda dapat melakukan hal-hal dalam sehari yang biasanya membutuhkan waktu berminggu-minggu atau berbulan-bulan dalam C. Biasanya, ditambah dengan biaya perangkat keras yang murah dibandingkan dengan gaji pengembang, WAY lebih murah untuk menulis barang-barang dalam bahasa tingkat tinggi dan melemparkan perangkat keras pada kelambatan apa pun.

Alasan Jeff dan Joel berbicara tentang C menjadi bahasa "programmer nyata" adalah karena tidak ada pegangan di C. Anda harus mengalokasikan memori Anda sendiri, membatalkan alokasi memori itu, melakukan pemeriksaan batas-batas Anda sendiri, dll. Tidak ada hal seperti itu sebagai objek baru (); Tidak ada pengumpulan sampah, kelas, OOP, kerangka kerja entitas, LINQ, properti, atribut, bidang, atau semacamnya. Anda harus mengetahui hal-hal seperti pointer aritmatika dan cara melakukan dereferensi pointer. Dan, dalam hal ini, ketahui dan pahami apa itu pointer. Anda harus tahu apa itu stack frame dan apakah pointer instruksi itu. Anda harus tahu model memori arsitektur CPU yang sedang Anda kerjakan. Ada banyak pemahaman implisit tentang arsitektur komputer mikro (biasanya yangkomputer mikro yang sedang Anda kerjakan) saat memprogram dalam C yang tidak ada atau perlu saat pemrograman dalam sesuatu seperti C # atau Java. Semua informasi itu telah dimuat ke programmer compiler (atau VM).

Robert C. Barth
sumber
"Tumbuhkan lebih banyak perangkat keras pada masalahnya" hanya berfungsi di lingkungan yang sebenarnya memungkinkan. Pasar yang tertanam adalah contoh yang sempurna (dan itu adalah pasar yang sangat besar ).
Bob Somers
Jeff dan Joel blog semata-mata tentang sistem bisnis, bukan sistem embedded, jadi masuk akal untuk berasumsi bahwa itulah konteks di mana pertanyaan ini diajukan.
Robert C. Barth
1) .net code berjalan secepat kode C? Pernahkah Anda benar-benar menulis program C? 2) Mentalitas "melempar lebih banyak perangkat keras pada masalah" adalah mengapa mesin 1.3GHz dual core 2GB saya hampir tidak dapat mengimbangi Windows XP sementara mesin 800MHz 512MB saya terbang dengan versi terbaru dari Ubuntu.
Robert Gamble
Ya, saya sudah menulis C. Tidak semegah yang disangka orang. Dan proyek terlalu mahal. Ini kasus ekonomi sederhana. Saya menjalankan Win2k pada Pentium Pro 180MHz dengan 768MB RAM selama bertahun-tahun sebagai server email dan web. Itu berjalan dengan baik. Bukti anekdotal tidak ada artinya.
Robert C. Barth
C tidak "mulia" tetapi cepat, saya telah menulis cukup kode C dan C # untuk mengetahui bahwa C hampir selalu jauh lebih cepat daripada C # saat melakukan tugas yang sama. Untuk beberapa tugas dibutuhkan waktu lebih lama untuk dikembangkan daripada bahasa tingkat yang lebih tinggi, tetapi ini semua tentang menggunakan alat yang tepat untuk pekerjaan itu dan kadang-kadang C adalah itu.
Robert Gamble
1

Perbedaan antara otomatis dan manual, bahasa tingkat yang lebih tinggi adalah abstraksi yang otomatis. C / C ++ dikontrol dan ditangani secara manual, bahkan kode pengecekan error terkadang merupakan pekerjaan manual.

C dan C ++ juga dikompilasi bahasa yang berarti tidak ada yang menjalankan bisnis di mana-mana, bahasa-bahasa ini harus disesuaikan untuk perangkat keras yang bekerja dengan Anda sehingga menambahkan lapisan tambahan gotcha. Meskipun ini sedikit menakutkan sekarang karena kompiler C / C ++ menjadi lebih umum di semua platform. Anda dapat melakukan kompilasi lintas antar platform. Ini masih bukan situasi berjalan di mana-mana, pada dasarnya Anda menginstruksikan kompiler A untuk mengkompilasi terhadap kompiler B kode yang sama arsitektur yang berbeda.

Intinya bahasa C tidak dimaksudkan untuk mudah dipahami atau alasan, ini juga mengapa mereka disebut sebagai bahasa sistem. Mereka keluar sebelum semua omong kosong abstraksi tingkat tinggi ini. Ini juga mengapa mereka tidak digunakan untuk pemrograman web front end. Mereka tidak cocok dengan tugas itu, maksud mereka untuk memecahkan masalah rumit yang tidak dapat diselesaikan dengan perkakas bahasa konvensional.

Inilah sebabnya mengapa Anda mendapatkan hal-hal gila seperti (mikro-arsitektur, driver, fisika kuantum, Game AAA, sistem operasi) ada hal-hal yang cocok untuk C dan C ++. Kecepatan dan angka menjadi area utama.

Val
sumber
1

C cepat karena dikompilasi secara asli, bahasa tingkat rendah. Tapi C bukan yang tercepat. The Rekursif Fibonacci benchmark menunjukkan bahwa Rust, Crystal, dan Nim bisa lebih cepat.

Bill Zelenko
sumber
1

Ada banyak alasan, termasuk:

  • Ini dikompilasi ke dalam bahasa assembly.
  • Ini diketik secara statis.
  • Tidak ada pengumpulan sampah.
  • Tidak ada penanganan kesalahan.
  • Banyak bahasa pemrograman menambahkan fitur baru. Bagian dari filosofi C adalah menjaga segala sesuatunya sederhana alih-alih menambahkan lebih banyak fitur.
Sapphire_Brick
sumber
Mengapa harus lebih cepat karena bukan objek-orionted?
sb27
A) pemrograman berorientasi objek menciptakan kebutuhan untuk pengumpulan sampah, B) fitur-fitur besar seperti pemrograman berorientasi objek menambah kompleksitas ke kompiler,
Sapphire_Brick
A) Tidak. Lihat C ++ atau Rust. B) Ya, tetapi itu juga memberi peluang bagi Penyusun untuk optimisasi baru.
sb27
A) Rust memiliki pengumpulan sampah waktu kompilasi, dan c ++ memiliki pengumpulan sampah untuk kelas, itu sebabnya ia memiliki destruktor ,, B) kompleksitas yang dioptimalkan masih kompleksitas
Sapphire_Brick
A) Ini bukan pengumpulan sampah, manajemen memori harus dilakukan bahkan jika Anda membuat program Anda dalam perakitan B) Tidak. Abstraksi Lebih Banyak memungkinkan pengoptimal untuk membuat asumsi yang lebih baik.
sb27