コンパイラってえらいのねぇ


プログラムを書くとき、少し前までは、

    if ( x >= 16*64 ) {
        ……
    }
ていう部分を、
    if ( x >= 1024 ) {
        ……
    }
ってやってた。

これは、16*64 なんて計算(しかも掛け算だし)を実行中にやらせるより、自分でやっといたほうが速いいんじゃ? とか思っていたからだ。

でも、コンパイラってえらいのねぇ…
こんな、定数どうしの演算だったら、当然定数の結果が出てくるわけで、コンパイルの時点でちゃーんと変換しといてくれるのね。
ワシのやってたこと、まるで無意味じゃーん?
むしろ、手計算しないほうがソースの意味わかりやすいなら、そのまんまにしといたほうがいいんじゃ?


そういや、ゲームプログラミングで良く使う(?)
    if ( ○○ || ▽▽ || □□ || ×× ) {
        ……
    }
ってヤツの、( )の中の順番って結構重要なんですなぁ。
これってば、「||」演算ばっかりだと、どれかが真(TRUE)になった時点で式全体がTRUEに決定しちゃうから、 ( )の中は、TRUEになる確率の高いヤツを左に書いたほうが、条件判定が早く済むから速いらしいっす。
とくにゲームみたく判定を何度も繰り返すようなプログラムでは、こーゆー小さなところが重要なのかも。
(でも、それより重要なのはアルゴリズムそのものっすよね。きっと)

逆に、
    if ( ○○ && ▽▽ && □□ && ×× ) {
        ……
    }
の場合は、当然左に FALSE になる確率の高いヤツを持ってきたほうがいいんでしょう。


そいえば、最適化って言やぁ
void GameMain ()
{
    flag = TRUE ;
    
    ……

    white ( flag ) {
        ……
    }
}
って感じので、whileループ内を繰り返していて、外部割り込みとかのイベントで、「flag」の値をFALSEにしてループを抜けよう! って考えていても、コンパイラが
「この関数の中で「flag」の値ってずっとTRUEじゃん?」
って思ちゃって
    while ( TRUE ) {
        ……
    }
って換えちゃうんで、無限ループになっちゃったー。
なんてコトになるらしい。

こんな時は、変数flagになんか指定してやるやつがあったよねー。
(確か「vなんとか」だったような…)
これを付けるとコンパイラがその変数に関して最適化をしないんで、期待通りに動くので、めでたしめでたし。



< Back to Diary.