Ví dụ, SysInternals cụ "FileMon" từ quá khứ có một trình điều khiển kernel-mode có mã nguồn là hoàn toàn trong một tập tin 4.000 dòng. Điều tương tự cho chương trình ping đầu tiên từng được viết (~ 2.000 LỘC).
Ví dụ, SysInternals cụ "FileMon" từ quá khứ có một trình điều khiển kernel-mode có mã nguồn là hoàn toàn trong một tập tin 4.000 dòng. Điều tương tự cho chương trình ping đầu tiên từng được viết (~ 2.000 LỘC).
Câu trả lời:
Sử dụng nhiều tập tin luôn đòi hỏi chi phí quản trị bổ sung. Người ta phải thiết lập một tập lệnh xây dựng và / hoặc makefile với các giai đoạn biên dịch và liên kết riêng biệt, đảm bảo các phụ thuộc giữa các tệp khác nhau được quản lý chính xác, viết tập lệnh "zip" để phân phối mã nguồn dễ dàng hơn qua email hoặc tải xuống, và vì vậy trên, bật. Các IDE hiện đại ngày nay thường chịu rất nhiều gánh nặng đó, nhưng tôi khá chắc chắn vào thời điểm khi chương trình ping đầu tiên được viết, không có IDE nào như vậy. Và đối với các tệp nhỏ ~ 4000 LỘC, không có IDE như vậy quản lý nhiều tệp cho bạn, việc đánh đổi giữa chi phí được đề cập và lợi ích từ việc sử dụng nhiều tệp có thể cho phép mọi người đưa ra quyết định cho cách tiếp cận tệp duy nhất.
Bởi vì C không giỏi về mô đun hóa. Nó trở nên lộn xộn (các tệp tiêu đề và #incoides, các hàm ngoài, lỗi thời gian liên kết, v.v.) và càng nhiều mô-đun bạn mang vào, nó càng khó hơn.
Các ngôn ngữ hiện đại hơn có khả năng mô đun hóa tốt hơn một phần vì chúng học được từ những sai lầm của C và chúng giúp dễ dàng phân tách cơ sở mã của bạn thành các đơn vị nhỏ hơn, đơn giản hơn. Nhưng với C, có thể có ích để tránh hoặc giảm thiểu tất cả những rắc rối đó, ngay cả khi điều đó có nghĩa là bỏ đi những gì sẽ được coi là quá nhiều mã vào một tệp.
Ngoài các lý do lịch sử, có một lý do để sử dụng điều này trong phần mềm nhạy cảm hiệu năng hiện đại. Khi tất cả các mã nằm trong một đơn vị biên dịch, trình biên dịch có thể thực hiện tối ưu hóa toàn bộ chương trình. Với các đơn vị biên dịch riêng biệt, trình biên dịch có thể tối ưu hóa toàn bộ chương trình theo một số cách nhất định (ví dụ: nội tuyến mã nhất định).
Trình liên kết chắc chắn có thể thực hiện một số tối ưu hóa ngoài những gì trình biên dịch có thể làm, nhưng không phải tất cả. Ví dụ: các trình liên kết hiện đại thực sự rất giỏi trong việc tách biệt các hàm không được ước tính, thậm chí trên nhiều tệp đối tượng. Họ có thể thực hiện một số tối ưu hóa khác, nhưng không có gì giống như những gì trình biên dịch có thể làm bên trong một hàm.
Một ví dụ nổi tiếng của mô-đun mã nguồn đơn là SQLite. Bạn có thể đọc thêm về nó trên trang Hợp nhất SQLite .
1. Tóm tắt
Hơn 100 tệp nguồn riêng biệt được ghép nối thành một tệp lớn mã C có tên "sqlite3.c" và được gọi là "sự hợp nhất". Sự hợp nhất chứa mọi thứ mà một ứng dụng cần để nhúng SQLite. Tệp hợp nhất có độ dài hơn 180.000 dòng và kích thước hơn 6 megabyte.
Kết hợp tất cả mã cho SQLite vào một tệp lớn giúp SQLite dễ triển khai hơn - chỉ có một tệp để theo dõi. Và bởi vì tất cả các mã nằm trong một đơn vị dịch thuật, trình biên dịch có thể thực hiện tối ưu hóa quy trình liên tục tốt hơn dẫn đến mã máy nhanh hơn từ 5% đến 10%.
$(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(CFILES)
so với việc di chuyển mọi thứ sang một tệp soudce. Bạn thậm chí có thể thực hiện việc biên dịch toàn bộ chương trình như là một mục tiêu thay thế cho tập lệnh xây dựng truyền thống bỏ qua việc biên dịch lại các tệp nguồn không thay đổi, tương tự như cách mọi người có thể tắt cấu hình và gỡ lỗi cho mục tiêu sản xuất. Bạn không có tùy chọn đó nếu mọi thứ nằm trong một nguồn lớn. Đó không phải là những gì mọi người đã quen, nhưng không có gì rườm rà về nó.
Ngoài yếu tố đơn giản mà người trả lời khác đã đề cập, nhiều chương trình C được viết bởi một cá nhân.
Khi bạn có một nhóm các cá nhân, việc phân chia ứng dụng trên một số tệp nguồn để tránh xung đột vô cớ trong các thay đổi mã trở nên mong muốn. Đặc biệt là khi có cả những lập trình viên tiên tiến và rất trẻ đang làm việc trong dự án.
Khi một người làm việc một mình, đó không phải là vấn đề.
Cá nhân, tôi sử dụng nhiều tập tin dựa trên chức năng như một thói quen. Nhưng đó chỉ là tôi.
Bởi vì C89 không có inline
chức năng. Điều đó có nghĩa là việc chia nhỏ tệp của bạn thành các hàm gây ra chi phí đẩy các giá trị lên ngăn xếp và nhảy xung quanh. Điều này đã thêm khá nhiều chi phí cho việc triển khai mã trong 1 câu lệnh chuyển đổi lớn (vòng lặp sự kiện). Nhưng một vòng lặp sự kiện luôn khó thực hiện hiệu quả (hoặc thậm chí chính xác) hơn nhiều so với giải pháp được mô đun hóa nhiều hơn. Vì vậy, đối với các dự án quy mô lớn, mọi người vẫn sẽ chọn không tham gia mô đun hóa. Nhưng khi họ đã nghĩ ra thiết kế trước và có thể kiểm soát trạng thái trong 1 tuyên bố chuyển đổi, họ đã chọn điều đó.
Ngày nay, ngay cả trong C, người ta không cần phải hy sinh hiệu năng để mô đun hóa bởi vì ngay cả trong các chức năng C cũng có thể được nội tuyến.
inline
từ khóa trong trình biên dịch C89 không thể nội tuyến, đó là lý do tại sao bạn phải viết mọi thứ trong một hàm khổng lồ là không chính xác. Bạn gần như không bao giờ sử dụng inline
như một tối ưu hóa hiệu suất - trình biên dịch nói chung sẽ biết rõ hơn bạn dù thế nào (và cũng có thể bỏ qua từ khóa).
inline
từ khóa có ngữ nghĩa mối liên kết liên quan đến mà quan trọng hơn vấn đề có hay không để thực hiện tối ưu hóa nội dòng, nhưng một số hiện thực có chỉ thị khác để kiểm soát trong lót và những thứ như vậy đôi khi có thể rất quan trọng. Trong một số trường hợp, một chức năng có thể trông quá lớn để có giá trị xếp hàng, nhưng việc gập liên tục có thể làm giảm kích thước và thời gian thực hiện xuống gần như không có gì. Một trình biên dịch không được khuyến khích mạnh mẽ để khuyến khích nội tuyến có thể không ...
Đây được coi là một ví dụ về sự tiến hóa, điều mà tôi ngạc nhiên chưa được đề cập.
Trong những ngày đen tối của lập trình, việc biên dịch một TẬP TIN có thể mất vài phút. Nếu một chương trình được mô đun hóa, thì việc bao gồm các tệp tiêu đề cần thiết (không có tùy chọn tiêu đề được biên dịch trước) sẽ là một nguyên nhân bổ sung đáng kể của sự chậm lại. Ngoài ra, trình biên dịch có thể chọn / cần giữ một số thông tin trên đĩa, có thể không có lợi ích của tệp hoán đổi tự động.
Các thói quen mà các yếu tố môi trường này đã dẫn đến các hoạt động phát triển đang diễn ra và chỉ dần dần thích nghi theo thời gian.
Tại thời điểm thu được từ việc sử dụng một tệp sẽ tương tự như chúng ta có được bằng cách sử dụng ổ SSD thay vì ổ cứng.