for文はインクリメントとデクリメント、どっちが早い?

前置き

 大学では少々処理速度の求められるプログラムを書いてました。 当然プログラム中ではfor文、while文を多用します。 どうしたら早いプログラムが書けるのか。
 そういうことを調べている中、for文の書き方としてインクリメントではなく デクリメントで書いた方がアセンブリ言語で書いた場合、行数が減ることになり 速度が出ると言う記述を見かけたことがありました。 正確なことを記述すれば、終了判定が0より大きいということがポイントだったと記憶してます。
 んじゃ、実際どうなんだというのが今回の記事の内容です。

比較内容

 for文で同じ回数だけループさせた場合にどの程度計算出来るのかを比較します。 1つはインクリメント、もう1つはデクリメントを使用したfor文を用意しそれぞれを比較します。
 で、実際に演算速度を比較してみます for文の繰り返し回数は100回、これが1000msec中何回何度実行出来るかと言うことを見ていきます。 これを400回繰り返し、1000msec中100回ループのfor文が平均何回実行出来るかを示します。

環境など

ソースコード

#include <stdio.h>
#include <time.h>
 
#define REPEAT 400
#define ITER   100
#define TIME   1000
 
unsigned long score;
long sum;
int j;
 
void plus(void){
    for(j=0; j<ITER; j++){
        sum += 1;
    }
    score += 1;
}
 
void minus(void){
    for(j=ITER; j>0; j--){
        sum += 1;
    }
    score += 1;
}
 
int main(void){
    FILE *fp = ::fopen("record.csv","w");
    clock_t start;
 
    fprintf(fp,"plus,sum,minus,sum\n");
 
    for(int i=0; i<REPEAT; i++){
        start = clock();
 
        score = 0;
        sum = 0;
        start = clock();
        while(clock()-start < TIME){
            plus();
        }
        fprintf(fp,"%d,%d,",score,sum);
 
        score = 0;
        sum = 0;
        start = clock();
        while(clock()-start < TIME){
            minus();
        }
        fprintf(fp,"%d,%d,",score,sum);
 
        fprintf(fp,"\n");
        printf("%d\n",i);
    }
 
    fclose(fp);
 
    return 0;
}
 for文の繰り返し回数は100回と一瞬で終わるような数字に設定しています。 これはインクリメントとデクリメントの結果の差が終了判定にあるということに起因しています。 for文中では変数sumを足していますが、この結果はダミーです。 このsumの役割はfor文が最適化されて消えてしまわないような狙いがあります。 最終的にこのsumをファイルに出力させることにより、これを実現しています。

結果・考察?

 結果を以下に載せます。 縦軸が計算回数の平均値、ラベルのplusがインクリメントの計算結果でminuseがデクリメントの計算結果を示しています。 計算回数を縦軸に取っているので、大きければ大きいほど良い結果を表しています。 Visual C++のコンパイルモードにはDebugモードとReleaseモードの2種類あるため、分けて表示しています。 Releaseモードは色々とコンパイラが最適化を行うらしく、 不要な計算が削除される、最適な計算順序などに行が入れ替わってコンパイルなどがされるみたいです。
 で、その結果見れば2つの計算方法にほぼ違いが見られないと言うことが言えます。 差があるのはコンパイルの差だけでインクリメントの計算方法でReleaseモードの方が12.8倍、 デクリメントの方では12.6倍もの差がありました。 …正直この違いを見る意味はほどんど無いと考えてます。
 各回ごとのインクリメントとデクリメントもほとんど差がありませんでした。 Debugモードでは差が出ると思っていただけにちょっと落胆した結果でした。
総合結果一覧
 for文ではインクリメントをしようとデクリメントしようが変わらない。
以上!
さすがはVisual C++コンパイラ、天晴れですとでも言っておくことにします。
This site is created by ez-HTML