Làm thế nào để bạn xử lý thời gian biên dịch ngày càng dài khi làm việc với các mẫu?


13

Tôi sử dụng Visual Studio 2012 và anh ấy có trường hợp chúng tôi đã thêm các tham số mẫu vào một lớp "chỉ" để giới thiệu "điểm đường may" để trong bài kiểm tra đơn vị, chúng tôi có thể thay thế các phần đó bằng các đối tượng giả.

Làm thế nào để bạn thường giới thiệu các điểm đường may trong C ++: sử dụng giao diện và / hoặc trộn dựa trên một số tiêu chí với giao diện ngầm bằng cách sử dụng các tham số mẫu cũng? Một lý do để hỏi điều này cũng là vì khi biên dịch đôi khi một tệp C ++ (bao gồm các tệp mẫu, cũng có thể bao gồm các mẫu khác) dẫn đến một tệp đối tượng được tạo theo thứ tự khoảng 5-10 giây trên máy của nhà phát triển .

Trình biên dịch VS cũng không đặc biệt nhanh trong việc biên dịch các mẫu theo như tôi hiểu và do mô hình bao gồm các mẫu (thực tế bạn bao gồm định nghĩa của mẫu trong mỗi tệp sử dụng nó một cách gián tiếp và có thể khởi tạo lại mẫu đó mỗi khi bạn sửa đổi một cái gì đó không liên quan gì đến mẫu đó) bạn có thể gặp vấn đề với thời gian biên dịch (khi thực hiện biên dịch gia tăng).

Cách xử lý thời gian biên dịch gia tăng (và không chỉ) của bạn là gì khi làm việc với các mẫu (bên cạnh trình biên dịch tốt hơn / nhanh hơn :-)).


1
@RobertHarvey tiêm phụ thuộc được thực hiện bằng cách sử dụng các tham số mẫu. Trong mã sản xuất nơi tôi khởi tạo chúng, tôi có thời gian biên dịch chậm.
Ghita

5
Bạn đang sử dụng C ++ 11? xem en.wikipedia.org/wiki/C%2B%2B11#Extern_template
mike30

2
Vì Andrei Alexandrescu đã viết "Thiết kế C ++ hiện đại", rất nhiều lập trình viên C ++ nghĩ rằng họ phải sử dụng các mẫu cho tất cả mọi thứ và để trình biên dịch xử lý càng nhiều càng tốt. Điều đó thường dẫn đến những hiệu ứng mà bạn đang mô tả. Trước đây (và hiện tại vẫn dành cho lập trình viên sử dụng các ngôn ngữ khác), hoàn toàn ổn khi không sử dụng các mẫu và xử lý những thứ như tiêm phụ thuộc với cơ chế thời gian chạy, ngay cả khi điều này cần một số CPU quay vòng nhiều hơn cho người dùng cuối (mà anh ta sẽ hầu như không bao giờ nhận thấy ). Thành thật mà nói, tôi chắc chắn Robert đúng 100% và đó là cách bạn nghĩ về nó.
Doc Brown

1
@Ghita: IMHO sử dụng lập trình meta mẫu thường chỉ là một hình thức tối ưu hóa sớm (và đôi khi chỉ là quá mức cần thiết) - theo như bạn không viết lib như STL với các yêu cầu tương đương. Bạn đánh đổi một số hiệu suất đạt được trong thời gian biên dịch lớn hơn, ít bảo trì hơn và nhiều thông báo lỗi khó hiểu. Sử dụng "các mẫu bên ngoài" có thể giúp bạn trong thời gian ngắn, nhưng nếu tôi ở trong đôi giày của bạn, tôi cũng sẽ nghĩ về những cải tiến dài hạn.
Doc Brown

4
@DocBrown. Ngược lại, bạn có thể nói tránh các mẫu để cải thiện hiệu suất xây dựng là tối ưu hóa sớm. Mẫu là trừu tượng lý tưởng cho nhiều vấn đề.
mike30

Câu trả lời:


9

Nếu các tham số mẫu của bạn chỉ có thể giả sử một tập hợp các giá trị hữu hạn (và nhỏ), bạn có thể di chuyển định nghĩa của chúng trong tệp nguồn và sử dụng tính năng khởi tạo rõ ràng .

Chẳng hạn, trong aaa.hbạn chỉ khai báo các hàm mẫu fg:

template <int n>
int f();

template <class T>
void g(int a);

Giả sử ntham số mẫu chỉ có thể là 1, 3, 6 và Ttham số mẫu chỉ có thể là int, longvoid *.

Sau đó, bạn xác định chúng aaa.cppnhư thế này:

template <int n>
int f()
{
    ...
}

template <class T>
void g(int a)
{
    ...
}

template int f<1>();
template int f<3>();
template int f<6>();

template void g<int>(int a);
template void g<long>(int a);
template void g<void *>(int a);

Theo cách này, trình biên dịch khởi tạo khuôn mẫu cho các tham số đã cho khi biên dịch aaa.cpp. Khi biên dịch mã máy khách, nó giả định rằng các định nghĩa tồn tại ở đâu đó và trình liên kết sẽ đảm nhiệm việc đó.

#include "aaa.h"

int main()
{
    f<1>();
    f<3>();
    f<6>();

    g<int>(5);
    g<long>(5);
    g<void *>(5);
}

Bạn cũng có thể khởi tạo các lớp mẫu một cách rõ ràng. Hạn chế là bạn không thể sử dụng fhoặc gvới các tham số mẫu khác.

#include "aaa.h"

int main()
{
    f<5>();
}

kết quả trong

undefined reference to `int f<5>()'

Tôi đã sử dụng kỹ thuật này trong một dự án trong đó một vài lớp phức tạp phụ thuộc vào một tập nhỏ (<10) tham số mẫu số nguyên và nó giảm đáng kể thời gian biên dịch (vì trình biên dịch không phải phân tích các định nghĩa mẫu phức tạp khi biên dịch mã máy khách) . Tất nhiên bạn có thể nhận được các cải tiến ít hơn, tùy thuộc vào mã thực tế.


2

Có lần tôi đã sử dụng một giải pháp lạ cho một vấn đề tương tự: Bao gồm cả STL dẫn đến thời gian biên dịch như vài giây cho mỗi tệp nguồn - bất kể nó nhỏ đến mức nào. Vì vậy, tôi đã bao gồm tất cả các tệp nguồn của mình vào một tệp chính và thời gian biên dịch cho mỗi tệp hầu như không thay đổi ... điều đó có nghĩa là tăng tốc độ của yếu tố 20+ vì tôi chỉ có một tệp duy nhất để biên dịch.

Để giữ cho thiết kế sạch sẽ, tôi tiếp tục duy trì một makefile, nhưng không bao giờ thực sự sử dụng nó (ngoại trừ việc xác minh nó vẫn hoạt động).


0

Chúng tôi đã từng thực hiện một nhiệm vụ lớn để xây dựng các tiêu đề được biên dịch sẵn và các mẫu được biên dịch trước qua đêm và chỉ xây dựng dựa trên những ngày hôm sau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.