2017-06-19 6 views
0

私は小さなシステムを作っており、システム全体で "冗長"なテキスト出力を切り替えたいと思っています。コンソール出力を "冗長"にする最速の方法

私はglobals.hと呼ばれるファイル作った:これが本当であるならば、私は、彼らはほとんど何でも、構築破壊、コピーややっているときに、すべての私のクラスは、コンソールにメッセージを印刷したい

namespace REBr{ 
    extern bool console_verbose = false; 
} 

を。例えば

:あなたが見ることができるよう

window(string title="",int width=1280,int height=720): 
Width(width),Height(height),title(title) 
{ 
    if(console_verbose){ 
     std::cout<<"Generating window #"<<this->instanceCounter; 
     std::cout<<"-"; 
    } 
    this->window=SDL_CreateWindow(title.c_str(),0,0,width,height,SDL_WINDOW_OPENGL); 
    if(console_verbose) 
     std::cout<<"-"; 
    if(this->window) 
    { 
     this->glcontext = SDL_GL_CreateContext(window); 
     if(console_verbose) 
      std::cout<<"."; 
     if(this->glcontext==NULL) 
     { 
      std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_OPENGLCONTEXT: "<<SDL_GetError()<<std::endl; 
     } 
    } 
    else std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_WINDOW: "<<SDL_GetError()<<std::endl; 
    if(console_verbose) 
     std::cout<<">done!"<<endl; 
} 

は今、私はそのコンストラクタでIFSの多くを持っています。そして、私は本当にそれを望んでいないので、それは私のアプリケーションを遅くするでしょう。私はこれを "ローディングバー"を取り除かずにできるだけ速くする必要があります(これは、プログラムがどの機能を停止したかを判断するのに役立ちます)。

これを達成する最善の方法は何ですか?私のシステムで


Everyingは、私は多くの場合、デバッグレベルをサポートLoggerクラスを使用REBr

+1

'console_verbose'を' constexpr'とマークしてください。式が 'false'として評価されれば、すべての' if'を最適化するようになります。 – Alexey

+1

また、 'if(...を入力しないようにするには) ''マクロを定義するだけです。#define VERB_STREAM if(console_verbose)std :: cout 'を使用し、' VERB_STREAM << "のように使用します。ウィンドウ"#<< this-> instanceCounter << ' - '; ' – chtz

+0

質問:https://stackoverflow.com/q/6692238/1632887 – seleciii44

答えて

1

いくつかの亜種:

  1. は、いくつかのロガーライブラリを使用してください。それは最大の柔軟性といくつかの有用な経験を与えるので、最良の選択肢です;)あなたは何かを工夫してはいけません。たとえば、Google GLOGをご覧ください。
  2. いくつかのマクロを定義すると、マクロのみを変更することでこれらのログをすべてオン/オフできます。しかし、そのようなマルコを正しく書くことはそれほど簡単ではありません。
  3. 条件フラグをconstexprに設定してください。そうすれば、フラグを切り替えることができ、その値に応じてコンパイラはコンパイルされたプログラムでifを最適化します。しかし、ifはまだコード内にあるので、やや大きめに見えます。

とにかく、これらのオプションはすべてプログラムの再コンパイルが必要です。再コンパイルを実行すると、最大速度を達成することは不可能です。

+0

非常に有益で、非常に詳細で、複数の回答が含まれています。ありがとう! – MoustacheSpy

0

名前空間の下にあります。呼び出しは次のようになります。

logger->Log(debugLevel, "%s %s %d %d", timestamp, msg, value1, value2); 

Loggerクラスは複数のデバッグレベルをサポートしているため、デバッグ出力を微調整できます。これは、コマンドラインまたはデバッガを使用していつでも設定できます。 Logステートメントは、printfのように可変長引数リストを使用します。

+0

このクラスをどのように正確にインスタンス化しますか?グローバルインスタンスを使用したい、またはグローバルインスタンスを作成するすべての関数のインスタンスを作成していますか?もしそうなら、なぜ名前空間内にいくつかの関数と変数を作るだけではないのですか? – MoustacheSpy

+0

@MoustacheSpy:メインルーチンでグローバルインスタンスをインスタンス化して、起動が予測可能になるようにします。私のアプリケーションはほぼ完全にオブジェクト指向であるため、関数よりもクラス/メソッドを使用していますが、これはカプセル化の明白な利点を超えて、やや恣意的です。また、複数のスレッドがログにアクセスしている場合は、スレッドセーフな保護が必要です。このクラスでは、ポリモーフィズムを使用して、スレッドセーフで非スレッドセーフな呼び出しを使用できます。 – Bruce

0

Google's logging moduleは、業界で広く使用されており、コマンドラインから設定できるロギングレベルをサポートしています。例えば、あなたはここにコードhttps://github.com/google/glogdoc/フォルダ内のドキュメントを見つけることができます

VLOG(1) << "I'm printed when you run the program with --v=1 or higher"; 
VLOG(2) << "I'm printed when you run the program with --v=2 or higher"; 

(そのドキュメントから撮影)。それを達成するために

関連する問題