2010-05-04 42 views
5

Tôi có một lớp rất cơ bản, đặt tên là Basic, được sử dụng trong hầu hết các tệp khác trong một dự án lớn hơn. Trong một số trường hợp, cần phải có đầu ra gỡ lỗi, nhưng trong chế độ phát hành, điều này không nên được kích hoạt và là một NOOP.Hiệu suất C++, tối ưu hóa trình biên dịch, chức năng trống trong .cpp

Hiện tại có một xác định trong tiêu đề, nút này sẽ bật hoặc tắt makro, tùy thuộc vào cài đặt. Vì vậy, đây chắc chắn là một NOOP, khi tắt. Tôi tự hỏi, nếu tôi có mã sau đây, nếu một trình biên dịch (MSVS/gcc) có thể tối ưu hóa ra các cuộc gọi chức năng, để nó lại là một NOOP. (Bằng cách đó, chuyển đổi có thể ở trong .cpp và chuyển đổi sẽ nhanh hơn nhiều, biên dịch/liên kết thời gian khôn ngoan).

--Header-- 
void printDebug(const Basic* p); 

class Basic { 
    Basic() { 
     simpleSetupCode; 

     // this should be a NOOP in release, 
     // but constructor could be inlined 
     printDebug(this); 
    } 
}; 
--Source-- 
// PRINT_DEBUG defined somewhere else or here 
#if PRINT_DEBUG 
void printDebug(const Basic* p) { 
    // Lengthy debug print 
} 
#else 
void printDebug(const Basic* p) {} 
#endif 

Trả lời

2

Như với tất cả các câu hỏi như thế này, câu trả lời là - nếu nó thực sự quan trọng với bạn, hãy thử cách tiếp cận và kiểm tra ngôn ngữ lắp ráp được phát ra.

+11

Người ủng hộ của Ma quỷ: không bao gồm một số lượng lớn các câu hỏi trên trang web này? Tại sao mọi người đến đây? Bởi vì họ không biết. Và bởi vì họ không biết cách tìm hiểu (trong trường hợp này có thể họ không nói lắp ráp), hoặc họ quá lười biếng hoặc vội vã làm như vậy. Câu hỏi thường gặp: chúng tôi có muốn chặn những người lười biếng/vội vã và chỉ trả lời những người thực sự không biết? Một số có thể bị miffed bởi FAQs (và có thể bỏ qua chúng); một số có thể thưởng thức nhận được pints một lần nữa và một lần nữa cho cơ bản cùng một câu hỏi. OP nên có ít nhất là tìm kiếm trang web này (hoặc google), mặc dù – Mawg

+0

@mawg Nó bao gồm rất nhiều công dụng của trang này, và đó là ý kiến ​​của tôi rằng có lẽ 50% các câu hỏi được đăng ở đây không nên hỏi. Điều này đặc biệt được hỏi thời gian và một lần nữa và câu trả lời của tôi là một trong những trung thực - chúng tôi không thể nói những gì optimiser của bạn sẽ làm gì với mã của bạn, chỉ có bạn mới có thể làm điều đó. –

+6

(-1) Vì vậy, câu trả lời của bạn không thực sự "hữu ích" đối với người dùng. Bạn đã không thực sự trả lời câu hỏi của họ, bất kể đó là một câu hỏi thích hợp hay không. Trong thực tế, bạn đã không bỏ phiếu để đóng như trùng lặp. Nếu tôi hỏi "2 + 2" là gì và bạn nói "tự mình tìm ra" bạn không * hữu ích * và bạn không * đúng *. Đúng là tôi nên tự mình tìm ra, nhưng bạn không ** trả lời tôi. Câu trả lời của bạn phải là nhận xét. – DevinB

1

Trình biên dịch có thể tối ưu hóa mã này, nếu nó biết việc triển khai hàm printDebug tại thời gian biên dịch. Nếu printDebug nằm trong một mô-đun đối tượng khác, điều này có thể chỉ được tối ưu hóa bởi trình liên kết, sử dụng tối ưu hóa toàn bộ chương trình. Nhưng cách duy nhất để kiểm tra điều này là đọc mã Assembly được tạo bởi trình biên dịch. Nếu bạn đã có PRINT_DEBUG vĩ mô, bạn có thể mở rộng nó bằng cách này như TRACE được định nghĩa:

 
#define PRINT_DEBUG // optional 
#ifdef PRINT_DEBUG 
#define PRINT_DEBUG_CALL(p) printDebug(p) 
#else 
#define PRINT_DEBUG_CALL(p) 
#endif 


void printDebug(const Basic* p); 

class Basic { 
    Basic() { 
     simpleSetupCode; 

     // this should be a NOOP in release, 
     // but constructor could be inlined 
     PRINT_DEBUG_CALL(this); 
    } 
}; 
--Source-- 
// PRINT_DEBUG defined somewhere else or here 
#if PRINT_DEBUG 
void printDebug(const Basic* p) { 
    // Lengthy debug print 
} 
#endif 
+0

Điều này chính xác là những gì được sử dụng. Nhưng chuyển đổi qua lại bằng cách sử dụng định nghĩa các vấn đề đó một dự án biên dịch lại. – Dodo

+0

Trên thực tế, đây không phải là những gì được sử dụng, theo mã của bạn. Trong phiên bản của tôi, chức năng printDebug và các cuộc gọi đến nó không tồn tại trong chương trình, khi PRINT_DEBUG không được xác định. Về biên dịch lại, có, cả hai phiên bản đều yêu cầu biên dịch lại. Nhưng bạn không thể mong đợi trình biên dịch để tối ưu hóa chức năng gọi trống mà không biên dịch lại ... –

+0

Tôi xin lỗi vì tôi chưa rõ. Mã tôi đã viết trong câu hỏi, không phải là mã trong sử dụng bởi các lớp cơ bản trong dự án của tôi. Tuy nhiên, mã bạn cung cấp về cơ bản là mã bằng với trạng thái hiện tại của lớp Cơ bản trong dự án của tôi. Với mã được cung cấp trong câu hỏi, thời gian biên dịch và liên kết giảm đáng kể so với phiên bản bạn cung cấp một số khác, khi xác định/hủy định nghĩa cờ PRINT_DEBUG. – Dodo

0

errm, tại sao không sử dụng tiền xử lý vĩ mô khác nhau?

Chỉ trong top đầu của tôi, một cái gì đó như:

#define DEBUG_TRACE(p) 
    #ifdef PRINT_DEBUG 
    printDebug(p); 
    #else 
    ; 
    #endif 
+0

Điều này không khác với những gì được sử dụng, chỉ được viết khác nhau. – Dodo

0

Hiện nay hầu hết các tối ưu hóa được thực hiện tại thời gian biên dịch. Một số trình biên dịch là LLVM có thể tối ưu hóa tại thời gian liên kết. Đây là một ý tưởng thực sự thú vị. Tôi đề nghị bạn hãy xem.

Đang chờ các loại tối ưu hóa này, những gì bạn có thể làm là như sau. Xác định macro cho phép bạn bao gồm câu lệnh sau tùy thuộc vào việc DEBUG có được xác định hay không.

#ifdef DEBUG 
#define IF_DEBUG (false) {} else 
#else 
#define IF_DEBUG 
#endif 

Bạn có thể sử dụng nó như thế này

Basic() { 
     simpleSetupCode; 

     // this should be a NOOP in release, 
     // but constructor could be inlined 
     IF_DEBUG printDebug(this); 
    } 

mà đã nhiều dễ đọc hơn so

Basic() { 
     simpleSetupCode; 

     // this should be a NOOP in release, 
     // but constructor could be inlined 
#if DEBUG 
     printDebug(this); 
#endif 
    } 

Lưu ý rằng bạn có thể sử dụng nó như thể nó là một từ khóa

IF_DEBUG { 
    printDebug(this); 
    printDebug(thas); 
} 
1
#if PRINT_DEBUG 
#define printDebug _real_print_debug 
#else 
#define printDebug(...) 
#endif 

Bằng cách này, bộ tiền xử lý sẽ loại bỏ tất cả các mã gỡ rối trước khi nó đến trình biên dịch.

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