JAVAの最適化(7)

今日は例から最適化をしてみます。

public void foo( int a , int b ){
    int i,j,k;
    for( i = 0 ; i < a ; i++ ){
        for( j = 0 ; j < b ; j++ ){
            for( k = 0 ; k < 10 ; k++ ){
                something( i , j , k );
            }
        }
    }
}

という関数をいろいろと弄ってみましょう。


まず、ループ変数をダウンカウンタにすることが挙げられます。
これは、ダウンカウンタの方が速いからではなくて、バイトコードは、0と比較する専用の命令があるので、0と比較することによって、バイトコードを少なくし、速度を上げることが出来ます。

public void foo( int a , int b ){
    int i,j,k;
    for( i = a - 1 ; i >= 0 ; i-- ){
        for( j = b - 1 ; j >= 0 ; j-- ){
            for( k = 9 ; k >= 0 ; k-- ){
                something( i , j , k );
            }
        }
    }
}

もちろん、ダウンカウンタでも正常に動くかどうかを考える必要があります。
無理なら諦めましょう。


次は、プライム変数のデクリメントを、省略せずに書くことにします。
この中でプライム変数になっているのは、a,b,iなので、i--をi=i-1に変更します。
どうやら、プライム変数に割り当てられた変数は、インクリメント、デクリメントの命令、iincを使うより、普通に演算した方が速いらしいです。

public void foo( int a , int b ){
    int i,j,k;
    for( i = a - 1 ; i >= 0 ; i=i-1 ){
        for( j = b - 1 ; j >= 0 ; j-- ){
            for( k = 9 ; k >= 0 ; k-- ){
                something( i , j , k );
            }
        }
    }
}

いや、むしろ、使用頻度が一番高いkをプライム変数に割り当てて、k=k-1とするべきかもしれません。

public void foo( int a , int b ){
    int k,j,i;
    for( i = a - 1 ; i >= 0 ; i-- ){
        for( j = b - 1 ; j >= 0 ; j-- ){
            for( k = 9 ; k >= 0 ; k=k-1 ){
                something( i , j , k );
            }
        }
    }
}


あと、aとbの使用頻度は低いのに、これがプライム変数に割り当てられているのが気になります。
なんとか、iとjに置き換えられないでしょうか。
ということで、このようにします。

public void foo( int i , int j ){
    int a = i;
    int b = j;
    int k;
    for( i = a - 1 ; i >= 0 ; i=i-1 ){
        for( j = b - 1 ; j >= 0 ; j=j-1 ){
            for( k = 9 ; k >= 0 ; k=k-1 ){
                something( i , j , k );
            }
        }
    }
}

引数をループ変数にしてやります。
これでかなり速くなりました。わーい。


……ん〜、なんかテンションが低い……なんでだろ。