条件を増やすか否か

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
cuser

条件を増やすか否か

#1

投稿記事 by cuser » 1年前

C での話です。C はそこそこ理解しているつもりです。

さて、ループの中に次のような if ブロックがあります。
ループの中ではこの前にも処理はあります。

コード:

if(mode == AUTO)
	oldData = newData;
if 文が真のときに実行されるのは 1 個の文です。
その前の処理によっては oldData と newData の値が同じときがあります。
こういうとき、もう 1 個条件を加えて次のようにしたほうが効率が良いのか、悪いのか知りたいです。

コード:

if(mode == AUTO && oldData != newData)
	oldData = newData;

アバター
あたっしゅ
記事: 663
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: 条件を増やすか否か

#2

投稿記事 by あたっしゅ » 1年前

東上☆海美☆「
前後がどうなってるかにもよりますので、この部分だけを観た感じですが、
oldData = newData; 自体は軽い処理なので、
毎回、oldData != newData を判定する必要は、ないのでは。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 条件を増やすか否か

#3

投稿記事 by usao » 1年前

そのように単純に比較を書けるのであれば組み込み型なのでしょうから,
仮に差が生じたとしても,ほぼどうでもいい程度なのではないでしょうか.

あえて効率を考えるなら,その条件判定がどのくらいの頻度で行われるのかを考える…かな?
例えば,このifが書かれている個所が相応の頻度で走るのだとして…
追加した判定がほとんどの場合に正となるのであれば,書かない方が効率は良いのかもしれない.

cuser

Re: 条件を増やすか否か

#4

投稿記事 by cuser » 1年前

【補足】
  1. oldData, newData はともに int 型です。
  2. 当該部分はループの最後の処理です。

アバター
あたっしゅ
記事: 663
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: 条件を増やすか否か

#5

投稿記事 by あたっしゅ » 1年前

東上☆海美☆「
条件判定 oldData != newData を実行する効率は無視ですか ?

何を作ろうとしているのか、わかりませんが、例えば、Game だとしたら、
『どうやったら Game そのものが面白くなるか』を考えるべき。

『oldData = newData; のせいで、プログラムが遅くなって、Game として成り立たない』ならともかく、
どうでもいいところの効率などは、考える必要は、ありません。

君も高専生なのかな ?
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 条件を増やすか否か

#6

投稿記事 by みけCAT » 1年前

例えばCompiler Explorerでコンパイルしてみると、以下のようになりました。

コード:

extern int mode, oldData, newData;
#define AUTO 123

void test1(void) {
    if(mode == AUTO)
    	oldData = newData;
}

void test2(void) {
    if(mode == AUTO && oldData != newData)
    	oldData = newData;
}

コード:

test1:
        cmpl    $123, mode(%rip)
        je      .L4
        ret
.L4:
        movl    newData(%rip), %eax
        movl    %eax, oldData(%rip)
        ret
test2:
        cmpl    $123, mode(%rip)
        je      .L7
.L5:
        ret
.L7:
        movl    newData(%rip), %eax
        cmpl    %eax, oldData(%rip)
        je      .L5
        movl    %eax, oldData(%rip)
        ret
このコンパイル結果では、mode == AUTO のチェックの通過後 (.L4、.L7)、
oldData != newData が無いバージョンではretまで3命令ですが、
あるバージョンではretまで4~5命令となりました。
また、どちらでも必ずnewDataおよびoldDataへのアクセスが発生します。
したがって、oldData != newData が無い方が効率が良さそうな気がします。

ただし、実際の実行速度は、分岐予測・命令の並行実行・キャッシュなどによって変わる可能性があり、
こっちの方が早いと断言することはできなそうです。
また、このコンパイル結果はあくまで例であり、
コンパイラ・最適化レベル・ターゲットなどによって変わる可能性があります。

「余計」な条件 && oldData != newData を書く分、コーディングの効率は落ちるかもしれないですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

cuser

Re: 条件を増やすか否か

#7

投稿記事 by cuser » 1年前

みけCAT さんが書きました:
1年前
例えばCompiler Explorerでコンパイルしてみると、以下のようになりました。
(mode == AUTO) が真の場合、test1(), test2() はともに
レジスターに newData を入れるんですね。
(オペランド間のデータの流れの方向が思っていたのとは違ったので最初は戸惑いました)

そして、その後の
(oldData != newData) が偽の場合、test1() と test2() では実行される命令の数が同じで、
(oldData != newData) が真の場合、test1() のほうが実行される命令の数が少ないんですね。

(分岐命令を別のものにすれば帰還命令を減らせてもう少し見やすくなったような気がします。
 機械がやることなので仕様がないですが ...)

【結論】
条件は加えないほうが良さそうですね。


解決しました。回答を下さった皆さん、ありがとうございます。

返信

“C言語何でも質問掲示板” へ戻る