Sebagai contoh, alat SysInternals "FileMon" dari masa lalu memiliki driver mode kernel yang kode sumbernya seluruhnya dalam satu file 4.000-baris. Hal yang sama untuk program ping pertama yang pernah ditulis (~ 2.000 LOC).
Sebagai contoh, alat SysInternals "FileMon" dari masa lalu memiliki driver mode kernel yang kode sumbernya seluruhnya dalam satu file 4.000-baris. Hal yang sama untuk program ping pertama yang pernah ditulis (~ 2.000 LOC).
Jawaban:
Menggunakan banyak file selalu memerlukan overhead administratif tambahan. Kita harus menyiapkan skrip build dan / atau makefile dengan tahapan kompilasi dan penautan yang terpisah, pastikan dependensi antara file yang berbeda dikelola dengan benar, menulis skrip "zip" untuk distribusi kode sumber yang lebih mudah melalui email atau unduh, dan sebagainya di. IDE modern saat ini biasanya mengambil banyak beban itu, tetapi saya cukup yakin pada saat program ping pertama kali ditulis, tidak ada IDE yang tersedia. Dan untuk file sekecil ~ 4000 LOC, tanpa IDE yang mengelola banyak file untuk Anda dengan baik, pertukaran antara overhead yang disebutkan dan manfaat dari menggunakan banyak file mungkin memungkinkan orang membuat keputusan untuk pendekatan file tunggal.
Karena C tidak pandai modularisasi. Itu menjadi berantakan (file header dan #include, fungsi extern, kesalahan waktu tautan, dll) dan semakin banyak modul yang Anda bawa, semakin sulit hasilnya.
Bahasa yang lebih modern memiliki kemampuan modularisasi yang lebih baik sebagian karena mereka belajar dari kesalahan C, dan mereka membuatnya lebih mudah untuk memecah basis kode Anda menjadi unit yang lebih kecil, lebih sederhana. Tetapi dengan C, akan bermanfaat untuk menghindari atau meminimalkan semua masalah itu, bahkan jika itu berarti menyamakan kode yang dianggap terlalu banyak ke dalam satu file.
Selain alasan historis, ada satu alasan untuk menggunakan ini dalam perangkat lunak sensitif kinerja modern. Ketika semua kode berada dalam satu unit kompilasi, kompiler dapat melakukan optimasi seluruh program. Dengan unit kompilasi terpisah, kompiler tidak dapat mengoptimalkan seluruh program dengan cara tertentu (misalnya inlining kode tertentu).
Linker tentu saja dapat melakukan beberapa optimasi selain apa yang dapat dilakukan oleh kompiler, tetapi tidak semua. Sebagai contoh: penghubung modern sangat bagus dalam menghilangkan fungsi yang tidak direferensikan, bahkan di banyak file objek. Mereka mungkin dapat melakukan beberapa optimasi lain, tetapi tidak seperti apa yang dapat dilakukan oleh kompiler di dalam suatu fungsi.
Salah satu contoh modul kode sumber tunggal yang terkenal adalah SQLite. Anda dapat membaca lebih lanjut tentang ini di halaman SQLite Amalgamation .
1. Ringkasan Eksekutif
Lebih dari 100 file sumber terpisah digabungkan menjadi satu file besar tunggal kode-C bernama "sqlite3.c" dan disebut "penggabungan". Penggabungan ini berisi semua yang dibutuhkan aplikasi untuk menanamkan SQLite. File amalgamasi memiliki panjang lebih dari 180.000 baris dan lebih dari 6 megabita.
Menggabungkan semua kode untuk SQLite ke dalam satu file besar membuat SQLite lebih mudah untuk digunakan - hanya ada satu file untuk dilacak. Dan karena semua kode berada dalam unit terjemahan tunggal, kompiler dapat melakukan optimasi antar-prosedur yang lebih baik sehingga menghasilkan kode mesin yang antara 5% dan 10% lebih cepat.
$(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(CFILES)
daripada memindahkan semuanya ke satu file soudce. Anda bahkan dapat melakukan kompilasi seluruh program sebagai target alternatif untuk skrip build tradisional yang melewatkan kompilasi ulang file sumber yang tidak berubah, mirip dengan cara orang mematikan profil dan debugging untuk target produksi. Anda tidak memiliki opsi itu jika semuanya berada dalam satu tumpukan besar sumber daya. Bukan seperti yang biasa dilakukan orang, tetapi tidak ada yang merepotkan.
Selain faktor kesederhanaan yang disebutkan oleh responden lain, banyak program C ditulis oleh satu orang.
Saat Anda memiliki tim yang terdiri dari beberapa individu, diinginkan untuk memecah aplikasi menjadi beberapa file sumber untuk menghindari konflik yang serampangan dalam perubahan kode. Terutama ketika ada kedua programmer yang sangat maju dan sangat junior bekerja pada proyek tersebut.
Ketika satu orang bekerja sendiri, itu bukan masalah.
Secara pribadi, saya menggunakan banyak file berdasarkan fungsi sebagai kebiasaan. Tapi itu hanya aku.
Karena C89 tidak memiliki inline
fungsi. Yang berarti bahwa memecah file Anda menjadi fungsi menyebabkan biaya mendorong nilai pada stack dan melompat-lompat. Ini menambahkan sedikit overhead daripada mengimplementasikan kode dalam 1 pernyataan switch besar (event loop). Tetapi suatu loop peristiwa selalu jauh lebih sulit untuk diterapkan secara efisien (atau bahkan dengan benar) daripada solusi yang lebih termodulasi. Jadi untuk proyek-proyek besar, orang masih akan memilih untuk melakukan modularisasi. Tetapi ketika mereka memiliki desain dipikirkan sebelumnya dan dapat mengontrol negara dalam 1 pernyataan switch, mereka memilih untuk itu.
Saat ini, bahkan dalam C, seseorang tidak perlu mengorbankan kinerja untuk memodulasi karena bahkan dalam fungsi C dapat digarisbawahi.
inline
kata kunci dalam kompiler C89 tidak bisa sejalan yang mengapa Anda harus menulis semuanya dalam satu fungsi raksasa tidak benar. Sebaiknya Anda tidak pernah menggunakan inline
pengoptimalan kinerja - kompiler pada umumnya akan lebih tahu daripada Anda (dan mengabaikan kata kunci).
inline
kunci tersebut memiliki semantik terkait tautan yang lebih penting daripada pertanyaan apakah melakukan optimasi in-line atau tidak, tetapi beberapa implementasi memiliki arahan lain untuk mengendalikan in-lining dan hal-hal semacam itu kadang-kadang bisa sangat penting. Dalam beberapa kasus, suatu fungsi mungkin terlihat terlalu besar untuk di-lining, tetapi pelipatan konstan dapat mengurangi ukuran dan waktu eksekusi menjadi hampir tidak ada. Kompiler yang tidak diberi dorongan kuat untuk mendorong in-lining mungkin tidak ...
Ini dianggap sebagai contoh evolusi, yang saya terkejut belum disebutkan.
Pada hari-hari gelap pemrograman, kompilasi satu FILE tunggal bisa memakan waktu beberapa menit. Jika suatu program dimodulasi, maka dimasukkannya file header yang diperlukan (tidak ada opsi header yang dikompilasi) akan menjadi penyebab tambahan yang signifikan dari perlambatan. Selain itu kompiler mungkin memilih / perlu menyimpan beberapa informasi pada disk itu sendiri, mungkin tanpa manfaat dari file swap otomatis.
Kebiasaan yang ditimbulkan oleh faktor-faktor lingkungan ini terbawa ke dalam praktik pembangunan yang sedang berlangsung dan hanya perlahan-lahan beradaptasi seiring waktu.
Pada saat itu keuntungan dari menggunakan satu file akan sama dengan yang kita dapatkan dengan menggunakan SSD, bukan HDD.