2012-02-20 5 views
2

私はhteコードを使用する場合、バイナリツリーを使用して値を検索するスイッチ構造のようにコンパイラが最適化しますか?現代のコンパイラは自動的に次のC++コードを最適化しますか?

if (X == "aaaa" || X == "bbbb" || X == "cccc" || X == "dddd") 
    { 

    } 
    else if (X == "abcd" || X == "cdef" || X == "qqqq") 
    { 

    } 

これは一例ですが、[OK]を、Xは文字列ですが、私は実際にそれがここで問題はないと思う引用記号

UPDATE

内に何のないパターンはありません私が知りたいのは、if内のすべてがすべて単一の変数であったときに最適化されます。

+0

「X」とは何ですか?カスタム '演算子=='または(おそらく 'const')' char * 'を持つ文字列クラスですか? – delnan

+0

@Aaron私はうまくいきません:-)オーバーロードされた 'operator =='を持つ 'std :: string'sが関係している限り、私は懐疑的ですが、このような単純な型を比較す​​るとクールな最適化が期待できます。 – Kos

+1

Re:あなたの編集:それは問題です!問題の '演算子=='が乱数を見たり、ロギングやスローをした場合はどうなりますか? – delnan

答えて

3

これらの値は、||または短絡オペレータの要件であるため、次々に比較されます。したがって、ここでは2つのことが起こります:

  • Xは右から左へ1つずつ比較されます。

    int hello() { 
        std::cout<<"Hello"; 
        return 10; 
    } 
    
    int world() { 
        std::cout<<"World"; 
        return 11; 
    } 
    
    int hello2() { 
        std::cout<<"Hello2"; 
        return 9; 
    } 
    
    int a = 10; 
    
    bool dec = (a == hello() || a == world()) 
    bool dec = (a == hello2() || a == hello() || a == world()) 
    

    用出力:例えば以下の場合

、すなわち(それは短絡OR演算子であるため)成功任意の比較後にNO MOREの比較があります

  • comparisoように、第2 Hello2 Helloのために、実行されません

    Hello 
    

    a == world()として、および:最初の文は次のようになりますnsは最初の成功まで起こっています。

    &&オペレータの場合、最初の失敗(これは文全体の結果を判断するのに十分です)まで比較が行われます。

  • +1

    短絡は、比較が観測可能な挙動を有する場合にのみ関連する。コンパイラの実装方法の違いを理解できない場合、それは公正なゲームです。 (明らかに、OPは、観察可能な比較を持ついくつかの奇妙な文字列クラスを使用している可能性がありますが、おそらくそうではありません) – GManNickG

    +0

    @GMan:OPは最適化に興味があるので、ベンチマークなどの場合は「観測可能」 。 – ams

    1

    おそらく設定したフラグによって異なります。バイナリツリーは検索が高速ですが、通常はより多くのコードを処理する必要があります。だから、サイズを最適化すれば、それはおそらく失われます。私はそれがとにかくそれをするかどうか分からない。 gccは多くのフラグに従って最適化されています。 O1、O2、O3、O4は、大きなグループのフラグを示す単純な形式です。ここにすべての最適化フラグのリストがあります:http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

    そのページの文字列、バイナリツリーなどを検索してみてください。

    0

    これをテストする最良の方法は、以下のような例です。 b変数の

    int a = 0; 
    int b = 0; 
    if(a == a || b++) { 
        ... 
    } 
    cout << b; 
    

    値が終わりに0であるべきです。 b++部分は実行されません。これは予想される動作ですが、コンパイラとその最適化設定に応じていくつかの例外が存在する可能性があります。 JavaScriptのような多くのスクリプティングランゲージもこのように動作します。

    1

    ほぼ確実ではありません。バイナリ検索には、何らかの並べ替えが必要です。 リレーションシップとless-thanの比較が可能です。コンパイラ はそれが存在するとは想定できません。見つけても は ==に相当する同値関係を定義することはできません。順序関係を定義する関数 が副作用を持たないことをコンパイラが判断できない可能性もあります。 ( に副作用がある場合、または式のいずれかの演算に、 の効果がある場合、コンパイラは ||の短絡動作を尊重しなければなりません)最後に、コンパイラがこれをすべて行ったとしても... 比較の順序を慎重に選択して、最も頻繁なケースが最初の になるようにしました。このような“の最適化”は、最終的に が悲観的になる可能性があります。これを処理する

    “正しい”(いくつかの状態が関係している場合や機能部品を多型ために、 )関数へのポインタに 文字列をマッピング、マップを作成することです。

    関連する問題