1

[明らかに] 条件が真の場合にのみ実行される if ステートメントがあります。この if ステートメントの後には、常に実行する必要があるコードがあり、その後に、最初と同じ条件で実行する必要がある別の if ステートメントがあります。

中央のコードは、スタックの特定の要素を使用して操作を実行しています。どちらかの側の if は、それぞれ操作の前後にスタックでプッシュ/ポップを実行します。

したがって、ロジックは次のようになります。

  1. スタックをプッシュする必要がありますか? はい・いいえ
  2. スタック上で操作を実行する
  3. スタックはプッシュされましたか? (はいの場合はポップ)

1と3は同じ状態です。

これは、C ++でこれを行うために最初に書いたコードです

#include <stdio.h>
#include <stdlib.h>

int somefunction(){
    return rand() % 3 + 1; //return a random number from 1 to 3
}

int ret = 0;


//:::::::::::::::::::::::::::::::::::::::
//  Option 1 Start
//:::::::::::::::::::::::::::::::::::::::
int main(){
    bool run = (ret = somefunction()) == 1; //if the return of the function is 1
    run = (run || (ret == 2));              //or the return of the function is 2
    if (run){                               //execute this if block
        //conditional code
        if (ret == 1){
            //more conditional code
        }
    }
        //unconditional code
    if (run){
        //even more conditional code
    }
}
//:::::::::::::::::::::::::::::::::::::::
//  Option 1 End
//:::::::::::::::::::::::::::::::::::::::

これを書いた後、これを行う方が効率的かもしれないと思いました:

//:::::::::::::::::::::::::::::::::::::::
//  Option 2 Start
//:::::::::::::::::::::::::::::::::::::::
int main(){
    bool run;
    if (run=(((ret = somefunction()) == 1)||ret == 2)){ //if the return of the function is 1 or 2 then execute this if block
        //conditional code
        if (ret == 1){
            //more conditional code
        }
    }
    //unconditional code
    if (run){
        //even more conditional code
    }
}
//:::::::::::::::::::::::::::::::::::::::
//  Option 2 End
//:::::::::::::::::::::::::::::::::::::::

最初の方法はいくつかの行に分割されているため、読みやすさを優先しますが、2 番目の方法では同じ行に 2 つの代入 (=) と 2 つの比較 (==) があります。2 番目の方法を使用する方がよいかどうか (効率または実行可能サイズの理由から)、または両方よりも優れた方法があるかどうかを知りたいです。

ほとんど計り知れないほどの違いしかないと誰かが言う前に、これは 1/50 秒以内に何千回も実行しなければならない巨大なループにあるので、できるだけ多くの時間を節約したいと思います。

4

4 に答える 4

5

パフォーマンスは気にする必要はありません。最新のコンパイラは通常、コードを最適化するのに十分なほどスマートです。コードが本質的に同じことをしている場合、結果は同じになります。

したがって、より読みやすい (したがって保守しやすい) バリアントを優先する必要があります。

私はそのようなものを書きます:

ret = somefunction();
// I don't know what is the semantics of ret == 1, so let's imagine some
bool operationIsPush = (ret == 1);
bool operationIsOnTop = (ret == 2);

if (operationIsPush || operationIsOnTop)
{
    //conditional code
}

if (operationIsPush)
{
    //more conditional code
}

//unconditional code

if (operationIsPush || operationIsOnTop)
{
    // ...
}
于 2012-07-19T11:10:46.800 に答える
1

bool を代入する 2 つの操作を 1 つに折りたたむかどうかよりも、正確性の方が重要です (コンパイラはおそらくいずれにせよそうします)。

スタックをプッシュ/ポップするには、スコープガードを使用する必要があります (元の記事はこちら)。これにより、何かが「無条件ビット」をスローした場合でも、確実にわからない場合でも、正しく動作することが保証されます。そうしないと、面白い驚きが得られます (1 つスタックするか、オーバーフローします)。

于 2012-07-19T11:13:48.217 に答える
1

ここでのパフォーマンスに違いはないと思います。最初の理由は、おそらくコンパイラがそれぞれのケースでコードを最適化するからです。2つ目は、操作の量ではなく、操作が行われる場所を変更するだけです(「私はA-> B-> CまたはA-> C-> Bを実行します」など)。したがって、常に同じ計算量になります。 (1 つの関数呼び出し、数回など==)。

ただし、これ (run=(((ret = somefunction()) == 1)||ret == 2)) はかなり読みにくいと考えてください。

于 2012-07-19T11:12:59.523 に答える
0

「if-else」を個別の巨大なループに分割できる状況があれば、より高速になります

それよりも

loop {  if_1  {some work}    if_2 {some other work}   }

あなたはできる

if_1 { loop {work }}    if_2 {loop{same work}}

さらに極端に言えば、最も内側の「if」文を分割できれば、(状況に応じて) 10 ~ 20 個の別個の巨大なループを作成でき、x2 x3 の速度で実行されます (「if」が原因で遅い場合)。

于 2012-07-19T11:13:34.747 に答える