Apakah kompiler mengkompilasi semua file header yang disertakan bersama dengan program utama setiap kali kita mengkompilasi program itu?

Menurut Wikipedia inilah yang dilakukan oleh C preprocessor:

"Praprosesor mengganti baris #include <stdio.h> dengan teks file 'stdio.h', yang antara lain mendeklarasikan fungsi printf()."

Jadi jika ini benar, program yang menyertakan lebih banyak file header akan memerlukan lebih banyak waktu untuk dikompilasi?


person user3125702    schedule 21.12.2013    source sumber
comment
Perlu diingat bahwa logika biasanya tidak masuk ke file .h. Ini berisi definisi konstanta, kelas dan fungsi, tetapi kodenya masuk ke file .c atau .cpp (yang tidak dikompilasi secara otomatis)   -  person SJuan76    schedule 21.12.2013
comment
Apakah definisi fungsi tidak berarti logika?   -  person ajay    schedule 21.12.2013
comment
@ajay, salahku, aku seharusnya mengatakan deklarasi   -  person SJuan76    schedule 21.12.2013
comment
@ SJuan76, coba baca header STL.   -  person SK-logic    schedule 22.12.2013


Jawaban (3)


Jadi jika ini benar, program yang menyertakan lebih banyak file header akan memerlukan lebih banyak waktu untuk dikompilasi?

Tentu saja. Sebenarnya, semakin banyak kode yang perlu dilihat oleh kompiler, semakin banyak waktu yang dibutuhkan untuk memprosesnya. Untuk beberapa proyek yang sangat besar, jumlah waktu yang diperlukan untuk melihat semua file dengan mudah menjadi perhatian. Hal ini terutama berlaku untuk kode templat yang sangat besar dan/atau kompleks, yang karena alasan praktis harus berada di file header. Pengorganisasian file header sendiri juga berdampak pada waktu kompilasi.

Namun, ini tidak sesederhana yang Anda bayangkan. Hal ini sangat bergantung pada kualitas implementasi (QOI) kompiler, dan kompiler modern saat ini sebenarnya cukup baik dalam menangani file header dalam banyak kasus.

Misalnya, GCC secara khusus mengenali penjaga penyertaan untuk mengurangi waktu pemrosesan. Dan kompiler saat ini menjadi lebih baik dalam menangani kode templat yang kompleks, misalnya. sebagian besar perpustakaan standar. Pada kompiler VC++, termasuk windows.h (yang memiliki prototipe fungsi untuk hampir seluruh keseluruhan Windows API) tidak terlalu meningkatkan waktu kompilasi menurut pengalaman saya. Dan jika semuanya gagal, banyak, jika tidak semua, kompiler memiliki fitur "header yang telah dikompilasi" yang dapat Anda gunakan .

Pada dasarnya, jangan khawatir sampai menjadi masalah. Jika memiliki lebih banyak file header membantu mengatur kode Anda dengan lebih baik, jangan ragu untuk menggunakannya.

person In silico    schedule 21.12.2013

Secara umum ya, program yang menyertakan lebih banyak file header akan memerlukan lebih banyak waktu untuk dikompilasi.


Sayangnya, konten header yang telah diproses sebelumnya dapat bervariasi tergantung pada simbol makro mana yang ditentukan dan bagaimana caranya. Dan khususnya header Microsoft umumnya dirancang untuk menghasilkan hasil yang berbeda tergantung pada simbol tersebut (dalam standar C++, ini terutama hanya simbol NDEBUG, yang mempengaruhi perluasan assert). Oleh karena itu, kompiler bersifat konservatif dan melakukan preprocessing dan kompilasi header berulang kali untuk setiap unit terjemahan.

Salah satu teknik umum untuk menghindari hal tersebut adalah apa yang disebut header yang telah dikompilasi.

Sejauh yang saya tahu, salah satu teknik yang tidak biasa, mungkin tidak diterapkan oleh kompiler mana pun, adalah mengizinkan pemrogram mengatakan bahwa "untuk kumpulan kompilasi ini Anda dapat berasumsi bahwa semua header akan diperluas ke hal yang sama", dan bahkan mungkin memilikinya sebagai < em>default (meskipun dapat memberikan hasil yang berbeda dari standar C++ ketika asumsi tidak berlaku).

Saya lebih memilih pendekatan yang terakhir, karena pendekatan ini akan mempercepat sebagian besar pembangunan apa pun, namun header yang telah dikompilasi adalah yang kami miliki dalam praktiknya.


David Vandevoorde mengerjakan modul proposal untuk C++.

Contoh bahasa dengan modul: Modula-2, Ada, UCSD Pascal.

Sayangnya ini belum siap untuk C++11, tapi mungkin kita akan mendapatkan modulnya nanti.

person Cheers and hth. - Alf    schedule 21.12.2013

Secara teori ya - semakin banyak kode, semakin lama waktu kompiler. Dan semua yang Anda sertakan, ditempatkan berdasarkan pra-prosesor, bukan pernyataan penyertaan seperti yang telah Anda sebutkan.

Praktisnya, hal ini bergantung pada apa yang Anda sertakan dan bagaimana caranya. Jika Anda memasukkan dengan cara yang benar, dampaknya terhadap kecepatan dapat diabaikan. Menyertakan terlalu banyak header standar akan menimbulkan polusi ruang nama dibandingkan masalah waktu kompilasi. Seluruh kode perpustakaan standar telah dikompilasi dan hanya akan ditautkan. Di Qt Anda dapat memasukkan masing-masing kelas secara terpisah (misalnya #include <QWidget>) atau - kemungkinan bagi programmer yang malas - memasukkan semua kelas dari modul (misalnya #include <QtGui>) yang mencakup ribuan header. Jadi saya tidak pernah melihat perbedaan waktu kompilasi yang signifikan antara kedua metode.

Beberapa pemikiran dan fakta membentuk pengalaman saya:

  • Secara silico disebutkan pelindung header. Tujuan utamanya bukan untuk optimasi waktu kompilasi tetapi untuk mencegah inklusi sirkular. Jadi jika Anda menyertakan header di 10 tempat, header tersebut hanya akan diurai satu kali.

  • Dalam C++ sertakan header hanya jika Anda berasal dari kelas di header itu. Kalau tidak, gunakan deklarasi maju.

  • Gunakan idiom implementasi pribadi - jadi header Anda hanya berisi satu/beberapa petunjuk.

  • Jangan sertakan header kode Anda, yang tidak Anda perlukan dalam file c/cpp itu. Sistem build yang baik menganalisis ketergantungan header berdasarkan pernyataan include. Kode Anda akan dikompilasi ulang secara tidak perlu setiap kali header yang disertakan berubah.

  • Selain waktu kompilasi, waktu penautan juga bisa memakan waktu lama. Pastikan, aplikasi tersebut terdiri dari DLL (file DLL/jadi) sehingga Anda dapat menghindari menghubungkan semuanya pada setiap kompilasi. Dalam satu proyek saya pernah mengalami waktu linking sekitar 10 menit. Pelanggan menolak menggunakan DLL karena beberapa alasan esoteris.

  • Jika waktu kompiler benar-benar menjadi masalah, ada baiknya mencari di balik terpal sistem build. Beberapa proyek yang tidak sepele harus menjalankan skrip pasca-/pra-pembuatan. Periksa apakah eksekusi skrip tersebut hanya dilakukan jika diperlukan.

  • Dalam satu proyek, waktu pembuatan yang lengkap dikurangi dari 4 jam menjadi 40 menit setelah melakukan beberapa modifikasi pada alat pembuat. Jika Anda menggunakan Linux, periksa dengan strace cara kerja make. Anda akan terkejut, betapa banyak akses file yang tidak diperlukan yang dilakukannya.

person Valentin Heinitz    schedule 21.12.2013