2015-04-20 23 views
6

Tôi có một dự án sử dụng khá nhiều mẫu lập trình C++. Điều này làm cho thời gian biên dịch dài. Tôi hiểu rằng tôi không thể có bánh và ăn nó nhưng tôi muốn biết một số lời khuyên và thủ thuật về làm thế nào để giảm thời gian biên dịch. Tôi đã thử các instantiations rõ ràng và trong khi điều đó có thể giúp trong một số trường hợp, rất nhiều lần, các cá thể là duy nhất đối với một đơn vị biên dịch cụ thể trong trường hợp instantiation instantiation không có gì để trợ giúp. Và bây giờ chúng ta chỉ nói về Clang, một công việc khá tốt. Khi tôi thử điều này trên G ++, thời gian biên dịch chỉ phát nổ. Đối với một tập tin, tôi đã từ bỏ việc chờ nó biên dịch sau 45 phút.Thủ phạm phổ biến cho sự chậm trễ TMP

  • Có thủ phạm phổ biến nào khi nói đến lập trình meta mẫu hay không, những thứ thường được biết là có vấn đề? Tôi nên tránh những kỹ thuật nào và tôi nên làm gì?
  • Có khu vực nào mà GCC được biết là hoạt động kém hơn Clang và có cách nào để giải quyết vấn đề này không?

Tôi đang sử dụng hầu hết các kỹ thuật vani C++ 11 thuần túy, tôi không sử dụng Boost MPL hoặc các thư viện tương tự.

Trả lời

0

Trong các dự án của chúng tôi, chúng tôi chỉ sử dụng tư duy và thử nghiệm. I E. đầu tiên chúng ta nghĩ "các mẫu phức tạp ở đây" là gì và sau đó chúng tôi đã cố gắng tách riêng các mẫu này hoặc loại bỏ chúng hoặc trình cấu trúc lại để xem liệu thời gian biên dịch có thay đổi hay không. Thường thì các mẫu biên dịch thời gian được đi kèm với việc sử dụng bộ nhớ tăng lên, tôi thậm chí còn báo cáo lỗi gcc một lần về vấn đề đó (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54056).

Có một mẹo khác đã giúp nhiều lần, bằng cách sử dụng công tắc dòng lệnh -Q (hiển thị các hàm mà gcc hiện đang biên dịch). Ví dụ. đối với lỗi được liên kết ở trên, rõ ràng là gcc bị chậm lại trên các mẫu lỗi đó.

2

Dưới đây là một số lời khuyên về Lập trình meta với C++ 11 và xa hơn nữa:

  • thích các thuật toán mở rộng variadic dựa. Các mẫu biến thể thường được xử lý nhanh chóng bởi trình biên dịch so với chuỗi O (n) của các bản mẫu ngay lập tức mà người ta thường cần cho các typelists và liên quan đến C++ 98/03 cũ. Tôi háo hức được thấy các biểu thức C++ 1z fold, như một cách để thực hiện fold metafuntcitons trong gia đình bằng cách sử dụng mở rộng gói.

  • Tránh chuỗi thừa kế: Thuật toán dựa trên kế thừa đệ quy thường hoạt động kém do trình biên dịch nên theo dõi siêu dữ liệu cây thừa kế. Ưu tiên các cuộc gọi thô đến ::type tiếp theo thay vì kế thừa trực tiếp từ "cuộc gọi" tiếp theo dưới dạng viết tắt để nhận được thành viên type đó.

  • thích thừa kế mở rộng gói để thừa kế đệ quy: Đó là, nếu bạn đang thực hiện một tuple như điều, thích

    template<typename... Ts> 
    struct tuple : Ts... 
    

    để

    template<typename Head, typename... Tail> 
    struct tuple : Head, tuple<Tail...> 
    

    kể từ khi trình biên dịch nên intantiate N phân nhóm về sau, cộng với chi phí thừa kế được mô tả ở điểm trên.

  • Ưu tiên các thuật toán dựa trên tra cứu tên: Tra cứu tên thường hoạt động nhanh hơn quá trình khởi tạo mẫu đệ quy.Vì vậy, hãy xem xét thực hiện một cái gì đó như decltype(declval<T>().f()) để tính toán một loại, trong đó kết quả là trong quá tải f chính xác.

+0

Thật không may, đây là những điều tôi đã làm. Một số điều mà tôi tìm thấy thực sự tăng thời gian biên dịch đã được sử dụng của tôi 'std :: make_shared' và' std :: shared_ptr'. Tôi đã thay thế bằng cách tính toán tham chiếu của riêng tôi bằng cách sử dụng 'std :: atomic' vì tôi đã xóa kiểu xóa. –

+0

@EmilEriksson Có thể vẫn sử dụng 'std :: shared_ptr' và không nhận được quá nhiều chi phí bổ sung http://blog2.emptycrate.com/content/template-code-bloat-revisited-smaller-makeshared – lefticus

+0

Trong trường hợp này, thậm chí nếu tôi giảm số lượng các cảnh báo 'std :: shared_ptr', tôi vẫn sẽ có quá nhiều điểm trong số đó và' std :: shared_ptr' tốn nhiều thời gian hơn so với triển khai của riêng tôi. Tất nhiên, nó là tốn kém cho một lý do chính đáng, sự linh hoạt là cần thiết cho một lớp thư viện chuẩn sẽ được sử dụng ở khắp mọi nơi. Nhưng tôi có một trường hợp sử dụng rất cụ thể và do đó, tôi đã có thể giảm thời gian biên dịch bằng cách sử dụng một giải pháp khác. –

Các vấn đề liên quan