C++中使用巨集定義來註釋掉所有的cout輸出

土豆西瓜大芝麻發表於2020-11-21

對於大一點的程式,為了驗證正確性,除了看直接的效果外,裡面還會增加一系列的cout輸出。在除錯過程中,也會增加一系列的輸出,但是當程式量大的時候,這些輸出的清楚將會變成很麻煩的事情。如何通過巨集定義依次註釋掉所有的輸出呢?本文給了嘗試。

直接上程式碼:

#include <iostream>
#define TRACE
#ifndef TRACE
 #define tcout 0 && cout//或者NULL && cout
#else
 #define tcout cout
#endif

using namespace std;

int main(){
 tcout<<"abdsa"<<endl;
 return 0;
}

#include <iostream>
//#define TRACE
#ifndef TRACE
 #define tcout 0 && cout
#else
 #define tcout cout
#endif

using namespace std;

int main(){
 tcout<<"abdsa"<<endl;
 return 0;
}

 

簡單吧。知其然而知其所以然,為啥呀?我們把tcout打出來,

#include <iostream>
//#define TRACE
#ifndef TRACE
 #define tcout 0 && cout //或者NULL && cout
#else
 #define tcout cout
#endif

using namespace std;

int main(){
 printf("%p\n",tcout);
 tcout<<"abdsa"<<endl;
 
 return 0;
}

發現0 &&cout計算後為nil。

#include <iostream>
#define TRACE
#ifndef TRACE
 #define tcout NULL && cout
#else
 #define tcout cout
#endif

using namespace std;

int main(){
 //printf("%p\n",tcout);
 0 && tcout<<"abdsa"<<endl;
 
 return 0;
}

 可以看到我們把0 &&挪到輸出前面,效果是一樣的,這說明cout其實並不是沒有被呼叫,只不過是執行完之後沒有輸出到console上來,因為把輸出到console緩衝區的內容和0或者NULL作了&&操作,才不輸出的。

但是這個是不是有開銷,我就不清楚了。如果有開銷,那麼這種並不是真正的解決方案,如果沒有開銷,或者說並沒有嘗試去將內容寫向console,那就可以作為解決方案。

 

我們再測試一下具體的時間:

(1)列印資料出來:耗時155ms左右

#include <iostream>
#include <sys/time.h>    
#include <unistd.h> 

#define TRACE
#ifndef TRACE
 #define tcout NULL && cout
#else
 #define tcout cout
#endif

using namespace std;


int main(){

struct timeval timeStart,timeEnd;
gettimeofday(&timeStart, NULL );
long runTime  = timeStart.tv_sec*1000000 +timeStart.tv_usec;

 //printf("%p\n",tcout);
 for(int i=0;i<100000;i++)
 {
 	//0 && tcout<<"abdsa"<<endl;
 	tcout<<"abdsa"<<endl;
 }
 gettimeofday(&timeEnd, NULL );
 runTime  = timeEnd.tv_sec*1000000 +timeEnd.tv_usec - runTime;
 printf("time consume: %ld\n",runTime);
 
 return 0;
}

(2)使用0 && cout,耗時721us

#include <iostream>
#include <sys/time.h>    
#include <unistd.h> 

#define TRACE
#ifndef TRACE
 #define tcout NULL && cout
#else
 #define tcout cout
#endif

using namespace std;


int main(){

struct timeval timeStart,timeEnd;
gettimeofday(&timeStart, NULL );
long runTime  = timeStart.tv_sec*1000000 +timeStart.tv_usec;

 //printf("%p\n",tcout);
 for(int i=0;i<100000;i++)
 {
 	0 && tcout<<"abdsa"<<endl;
 	//tcout<<"abdsa"<<endl;
 }
 gettimeofday(&timeEnd, NULL );
 runTime  = timeEnd.tv_sec*1000000 +timeEnd.tv_usec - runTime;
 printf("time consume: %ld\n",runTime);
 
 return 0;
}

(3)測試不列印任何輸出的情況下的耗時:737us

#include <iostream>
#include <sys/time.h>    
#include <unistd.h> 

#define TRACE
#ifndef TRACE
 #define tcout NULL && cout
#else
 #define tcout cout
#endif

using namespace std;


int main(){

struct timeval timeStart,timeEnd;
gettimeofday(&timeStart, NULL );
long runTime  = timeStart.tv_sec*1000000 +timeStart.tv_usec;

 //printf("%p\n",tcout);
 for(int i=0;i<100000;i++)
 {
 	//0 && tcout<<"abdsa"<<endl;
 	//tcout<<"abdsa"<<endl;
 }
 gettimeofday(&timeEnd, NULL );
 runTime  = timeEnd.tv_sec*1000000 +timeEnd.tv_usec - runTime;
 printf("time consume: %ld\n",runTime);
 
 return 0;
}

這說明,上述方法是一個可使用的解決方案,不會降低程式的效能。

 

如果要控制日誌的輸出,就用:

#ifndef TRACE
  #define tcout 0 && Loger::instance()::log
#else
  #define tcout Loger::instance()::log
#endif

 

相關文章