Beberapa alasan
File tajuk
Setiap unit kompilasi tunggal membutuhkan ratusan atau bahkan ribuan header untuk (1) dimuat dan (2) dikompilasi. Masing-masing dari mereka biasanya harus dikompilasi ulang untuk setiap unit kompilasi, karena preprocessor memastikan bahwa hasil kompilasi header mungkin bervariasi antara setiap unit kompilasi. (Makro dapat didefinisikan dalam satu unit kompilasi yang mengubah konten header).
Ini mungkin yang alasan utama, karena membutuhkan jumlah besar kode untuk dikompilasi untuk setiap unit kompilasi, dan tambahan, setiap kepala harus dikompilasi beberapa kali (sekali untuk setiap unit kompilasi yang mencakup itu).
Menautkan
Setelah dikompilasi, semua file objek harus dihubungkan bersama. Ini pada dasarnya adalah proses monolitik yang tidak bisa diparalelkan dengan baik, dan harus memproses seluruh proyek Anda.
Parsing
Sintaksnya sangat rumit untuk diuraikan, sangat bergantung pada konteks, dan sangat sulit untuk disatukan. Ini membutuhkan banyak waktu.
Templat
Di C #, List<T>
adalah satu-satunya jenis yang dikompilasi, tidak peduli berapa banyak instantiasi Daftar yang Anda miliki di program Anda. Dalam C ++, vector<int>
adalah tipe yang sepenuhnya terpisah dari vector<float>
, dan masing-masing harus dikompilasi secara terpisah.
Tambahkan ke ini bahwa templat membuat "sub-bahasa" Turing-lengkap lengkap yang harus ditafsirkan oleh kompiler, dan ini bisa menjadi sangat rumit. Bahkan kode metaprogramming templat yang relatif sederhana dapat menentukan templat rekursif yang membuat puluhan dan puluhan instantiasi templat. Template juga dapat menghasilkan tipe yang sangat kompleks, dengan nama yang sangat panjang, menambahkan banyak pekerjaan tambahan ke linker. (Itu harus membandingkan banyak nama simbol, dan jika nama-nama ini dapat tumbuh menjadi ribuan karakter, itu bisa menjadi cukup mahal).
Dan tentu saja, mereka memperburuk masalah dengan file header, karena template umumnya harus didefinisikan dalam header, yang berarti jauh lebih banyak kode harus diurai dan dikompilasi untuk setiap unit kompilasi. Dalam kode C sederhana, header biasanya hanya berisi deklarasi maju, tetapi kode aktual sangat sedikit. Di C ++, tidak jarang hampir semua kode berada di file header.
Optimasi
C ++ memungkinkan untuk beberapa optimasi yang sangat dramatis. C # atau Java tidak mengizinkan kelas untuk dihilangkan sama sekali (mereka harus ada di sana untuk tujuan refleksi), tetapi bahkan metaprogram template C ++ sederhana dapat dengan mudah menghasilkan puluhan atau ratusan kelas, yang semuanya digarisbawahi dan dihilangkan lagi dalam optimasi tahap.
Selain itu, program C ++ harus dioptimalkan sepenuhnya oleh kompiler. Program AC # dapat mengandalkan kompiler JIT untuk melakukan optimasi tambahan pada waktu buka, C ++ tidak mendapatkan "peluang kedua" semacam itu. Apa yang dihasilkan kompiler sama optimalnya dengan yang didapat.
Mesin
C ++ dikompilasi ke kode mesin yang mungkin agak lebih rumit daripada penggunaan bytecode Java atau .NET (terutama dalam kasus x86). (Ini disebutkan karena kelengkapan hanya karena disebutkan dalam komentar dan semacamnya. Dalam praktiknya, langkah ini tidak mungkin mengambil lebih dari sebagian kecil dari total waktu kompilasi).
Kesimpulan
Sebagian besar faktor ini dimiliki oleh kode C, yang sebenarnya mengkompilasi dengan cukup efisien. Langkah parsing jauh lebih rumit di C ++, dan dapat mengambil lebih banyak waktu secara signifikan, tetapi pelaku utama mungkin template. Mereka berguna, dan membuat C ++ bahasa yang jauh lebih kuat, tetapi mereka juga mengambil korban dalam hal kecepatan kompilasi.